user5047085
user5047085

Reputation:

Promise.all wrapper which can trap errors

I have this verbatim in a simple script:

Promise.all(links.map(function (l) {
  return Promise.resolve(require(l).r2gSmokeTest())
     .then((v:any) => ({path: l, result: v}));
}))
.then(function(results){

})
.catch(function(e){

}):

the problem is that if the require() call throws an error for whatever reason, the promise chain won't catch it.

is the simplest thing to do to avoid this to wrap Promise.all in a function, like so:

const getAllPromises = function(links){
   return Promise.resolve(null).then(function(){
       return Promise.all(links.map(function (l) {
         return Promise.resolve(require(l).r2gSmokeTest())
         .then((v:any) => ({path: l, result: v}));
}));

it seems to me that maybe Promise.all should have a different API, something like:

Promise.all(function(){
   return values.map(v => whatever);
});

that way any errors can be trapped, if Promise.all is not called within a Promise chain...

Upvotes: 0

Views: 256

Answers (2)

Karen Grigoryan
Karen Grigoryan

Reputation: 5422

Your require() is happening on the map level outside of Promise context, that's why it gets propagated immediately to the global level, so if you just wrap it into a new Promise it should handle the error as expected:

Promise.all(links.map(function(l) {
    return new Promise(resolve => resolve(require(l).r2gSmokeTest())) // <-- here
      .then((v: any) => ({
        path: l,
        result: v
      }));
  }))
  .then(function(results) {

  })
  .catch(function(e) {

  }):

Upvotes: 1

Bergi
Bergi

Reputation: 664237

Use an async function which can't throw - it will only return a rejected promise when an exception happens:

Promise.all(links.map(async function (l) {
  const v: any = await require(l).r2gSmokeTest();
  return {path: l, result: v};
}))

In general, the expectation for any function that does something asynchronous is to always return a promise and never throw synchronously. Your map callback should adhere to that - and try … catch (e) { return Promise.reject(e); } around the require call if necessary. You might also consider using a helper function that works like Bluebird's Promise.try.

Upvotes: 1

Related Questions