Log an error through Jobs

Can we log an error through Job?
Suppose If any condition doesn't match, it should throw an error which will be traced in Run History(like other errors).

Hi Sai,

What a great question! If something like createIf(…) or upsertIf(…) doesn’t get you the results you want, I’d go about it like this:

create(“foo”, fields(
field(“bar”, “baz”),
field(“qux”, (state) => {
if (state.data.some_condition) {
return "everything is awesome!"
} else {
throw new Error(“everything is the worst ¯\_(ツ)_/¯”);

Thanks Taylor.

But can we catch errors on basis of Salesforce field condition?
Like we get errors if external id value is not present in salesforce.
Same way for example if checkbox is checked(not present in state data) in salesforce then only upsert or else throw an exception in OpenFn.

OK… I think I understand. This is actually just how OpenFn works. See this failure notification from OpenFn in my Gmail inbox:


If you try to upsert in Salesforce but you don’t fulfill the validation requirements, the run “fails” on OpenFn and you get notified. In the example I’m using here, Salesforce rejected the upsert since there was no record with a matching external ID.

From a certain perspective, OpenFn’s job runs always succeed (in that they do what they’re told then store the results) but we’ve built the system in such a way that we can detect a soft failure from Salesforce (or any other endpoint) and pass it along to you—marking your run as “failed.” Does that make sense?

Let me know if I’m still missing your question here and I can send over some more examples. Also, I’d recommend setting up a basic job to load data into Salesforce and then seeing how you can alter your validation in Salesforce to make the job runs “fail” or “succeed”.


Yes. I understood that part.
I just want to confirm the upsertIf() logical condition part, whether it can check for salesforce field value.
for example I am trying to do like this
upsert(if(Spoiled__c === true) {
            throw new Error("everything is worst!");
          } , "Voucher__c", "Voucher_Code_Exernal_Id__c", fields(
         field("Voucher_Code_Exernal_Id__c", dataValue("voucher_id")),
   field("Amount__c", "222")
where Spoiled__c is a salesforce field on Voucher object.

Hey Sai,

First, it looks like you’ve got an extra parenthesis. Check out the docs for upsertIf (either on the platform or here). The structure should be:

upsertIf(true, ‘obj_name’, ‘ext_id’, {
attr1: “foo”,
attr2: “bar”

You can, of course, use fields(field(…)) instead of the object notation above.

The key is that this whole upsertIf(…) operation gets evaluated and resolves to a single API call on Salesforce if a logical is true—so that test can only be done on state. (i.e., something in your data, not in Salesforce’s data.) It sounds like what you’d like to do is query Salesforce with a first API operation, returning the data for a particular record, then perform another operation is that data passes a logical test. That’s a cool idea, and it shouldn’t be hard to implement using jsForce, but nobody’s added it to the Salesforce language-package yet. You’re welcome to give it a go and submit a PR!

If you’re still trying to throw an error on OpenFn, you could try creating a validation rule on Salesforce using “ISCHANGED” to block attribute changes to vouchers if Spoiled__c === true. What do you think?


Yes sure It is making sense to me.
Thanks for workaround.

You got it!