1

I have a function that calls itself recursively with different input when catching an error:

function getSomething(inputs, index) {

  var index = index || 0
    , indexMax = inputs.length - 1

  return new Promise((resolve, reject) => {
    //inputs[index].staff is an array and getSomethingElse returns a Promise
    Promise.all(inputs[index].staff.map(getSomethingElse))
    .then(output => {
      resolve(output)
    })
    .catch(reason => {
      if(index<indexMax)
        getSomething(inputs, index+1);
      else
        reject(reason);
    })
  })
}

getSomething(myInputs)
.then(output => {
  console.log('resolved with this:'+output);
})
.catch(reason => {
  console.log('rejected because of this:'+reason);
});

I get UnhandledPromiseRejectionWarning: Unhandled promise rejection error from getSomethingElse rejection. I think this rejection is not catched in the first function call as it expected it. How can I call the reject of the first function call ? or should I bring the first promise with me as an argument in each function call ?

cartman
  • 189
  • 1
  • 2
  • 17

2 Answers2

2

This is the promise constructor anti-pattern. The constructor is for wrapping legacy APIs only.

Instead, chain the promises like they were meant to by always returning all of them.

function getSomething(inputs, index = 0) {
  return Promise.all(inputs[index].staff.map(getSomethingElse))
    .catch(reason => {
      if (index >= inputs.length - 1) throw reason;
      return getSomething(inputs, index+1);
    })
  })
}
Community
  • 1
  • 1
jib
  • 40,579
  • 17
  • 100
  • 158
0

I just found the solution. In fact, I should have defined resolve and reject from the returned promise in order to be transmitted to the previous one:

 if(index<indexMax) {
   getSomething(inputs, index+1)
   .then(output => {
     resolve(output);
   })
   .catch(reason => {
      reject(reason);
   })
}
 else
   reject(reason);
cartman
  • 189
  • 1
  • 2
  • 17