Home > Software engineering >  How to stop processing continuing past a promise reject
How to stop processing continuing past a promise reject

Time:03-05

I have async code that I'd like to stop running when I reject.

Note:

let ingestPromises = event.Records.map(async (record, i) => {
    let camera = JSON.parse(record.body)
    return new Promise(async (resolve, reject) => {

        let imageBuffer;
        try {
            imageBuffer = await retrieveImageFromURI(camera.ing_uri)
            console.log(`Record #${i} Successful Ingestion from URI`);
        } catch (err) {
            console.log("Going to reject");
            reject({ 'Task': `Attempting to pull image from camera (${camera.camName}`})
            console.log("Rejected");
        }

        console.log("Going to save file now...");
   //    ... blah blah more code ...
})}

let settledPromises = await Promise.allSettled(ingestPromises)
console.log('All promises settled :>> ', settledPromises);

When I run this against an invalid uri, the retrieveImageFromURI function throws a timeout error as expected. This skips the "Record X successful ingestion..." message and jumps to the catch block as expected. However, then things go unexpectedly.

Output from the above code, when retrieveImageFromURI throws an error looks like this:

Going to reject
Rejected
Going to save file now...
All promises settled :>>  [ {
    status: 'rejected',
    reason: {
      Task: 'Attempting to pull image from camera (TEST Camera)'
    }
}]

It is my expectation that the reject would stop any further processing within that promise (much like a return would) and I would NOT see 'Rejected' nor 'Going to save file now...' console.logs...

What am I misunderstanding here?

CodePudding user response:

Add return to stop execution, since reject is just a function, it can't make the function stop executing.

try {
  // ...
} catch (err) {
  console.log("Going to reject");
  reject({
    'Task': `Attempting to pull image from camera (${camera.camName}`
  });
  console.log("Rejected");
  return;
}

If you have a finally clause, you will need to add a variable to keep track:

Note: This isn't helpful here, since finally is supposed to execute regardless of whether catch occurred, but if you have extra checks inside of catch, the return will go into the finally so an extra variable is needed.

let shouldReturn = false;
try {
  // ...
} catch (err) {
  console.log("Going to reject");
  reject({
    'Task': `Attempting to pull image from camera (${camera.camName}`
  });
  console.log("Rejected");
  let shouldReturn = true;
  return;
} finally {
  if (shouldReturn) return;
}

CodePudding user response:

There's nothing special about invoking reject. It's just a function. If you want to bail on further processing, your function should return.

try {
  imageBuffer = await retrieveImageFromURI(camera.ing_uri)
  console.log(`Record #${i} Successful Ingestion from URI`);
} catch (err) {
  console.log("Going to reject");
  reject({ 'Task': `Attempting to pull image from camera (${camera.camName}`})
  console.log("Rejected");
  return;
}

CodePudding user response:

Do I need to return after early resolve/reject? indicates that the first reject (or a resolve) will define the fullfilled value of a Promise, but they actively do NOT stop execution and a return is needed.

  • Related