Say we have 3 asynchronous tasks that return Promises: A
, B
and C
. We want to chain them together (that is, for sake of clarity, taking the value returned by A
and calling B
with it), but also want to handle the errors correctly for each, and break out at the first failure. Currently, I see 2 ways of doing this:
A
.then(passA)
.then(B)
.then(passB)
.then(C)
.then(passC)
.catch(failAll)
Here, the passX
functions handle each of the success of the call to X
. But in the failAll
function, we'd have to handle all of the errors of A
, B
and C
, which may be complex and not easy to read, especially if we had more than 3 async tasks. So the other way takes this into consideration:
A
.then(passA, failA)
.then(B)
.then(passB, failB)
.then(C)
.then(passC, failC)
.catch(failAll)
Here, we separated out the logic of the original failAll
into failA
, failB
and failC
, which seems simple and readable, since all errors are handled right next to its source. However, this does not do what I want.
Let's see if A
fails (rejected), failA
must not proceed to call B
, therefore must throw an exception or call reject. But both of these gets caught by failB
and failC
, meaning that failB
and failC
needs to know if we had already failed or not, presumably by keeping state (i.e. a variable).
Moreover, it seems that the more async tasks we have, either our failAll
function grows in size (way 1), or more failX
functions gets called (way 2). This brings me to my question:
Is there a better way to do this?
Consideration: Since exceptions in then
is handled by the rejection method, should there be a Promise.throw
method to actually break off the chain?
A possible duplicate, with an answer that adds more scopes inside the handlers. Aren't promises supposed to honor linear chaining of functions, and not passing functions that pass functions that pass functions?