0

This function is being called by a parent function, that should return the success object, or the error.

I'm having trouble using async while trying to retry a function 4 times. On success it's all good. On error, I'm getting "Unhandled Promise Rejection".

//create record
const createSFDCRecord = async (object, userData) => {
  console.log("trial", retryCount)
  return await conn.sobject(object).create(userData, async (err, ret) => {
    if (err || !ret.success) {
      if (retryCount < retryLimit) {
        setTimeout(async () => {
          return await createSFDCRecord(object, userData)
        }, 2000)
        retryCount++
      } else {
        pagerDutyEvent(
          `Failed to send ${userData.Trigger_Code_kcrm__c} form data into ${object} after 5x`,
          "error",
          err
        )
      }
    }
    console.log(`Created ${object} id : ${ret.id}`)
  })
}

sobject is from jsforce http://jsforce.github.io/jsforce/doc/SObject.html

2
  • 1
    This looks like you mix two styles, there's await but also a callback. What's worse, the callback is async which means that the caller would have to take this into account. This looks incorrect to me. Commented Aug 1, 2021 at 15:42
  • You code is completely incorrect, why do you have a return inside a setTimeout Commented Aug 1, 2021 at 15:57

1 Answer 1

2

You are mixing promises with callbacks:

  • sobject(object).create returns a promise, so there is no need to use the callback argument.
  • return with a value has no sense in a setTimeout callback. That returned value is going nowhere.
  • The promises resulting from the repeated attempts are not chained: the resolution of the first is not locked into the next one. Instead you have a stand alone promise in a setTimeout callback, whose resolution or rejection is not handled.

The "Unhandled Promise Rejection" happens because you have an await of a promise that can reject, yet you do not capture the exception that will be triggered at that line when this happens.

You should refactor this to something like this (untested code):

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

const createSFDCRecord = async (object, userData) => {
    let retryCount = 1;
    while (true) {
        console.log("trial", retryCount);
        try {
            let ret = await conn.sobject(object).create(userData);
            if (!ret.success) throw new Error("ret.success is false");
            console.log(`Created ${object} id : ${ret.id}`);
            return ret.id;
        } catch(err) {
            if (retryCount >= retryLimit) {
                pagerDutyEvent(
                   `Failed to send ${userData.Trigger_Code_kcrm__c} form data into ${object} after ${retryLimit}x`,
                   "error",
                   err
                );
                return -1; // Or throw an exception... but then deal with it.
            }
        }
        retryCount++;
        await delay(2000);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.