I know how to chain promises so that multiple success functions are executed. That is esplained in many examples. How do I chain promises so that multiple error functions are executed?
Asked
Active
Viewed 9,756 times
2 Answers
33
When an error is handled (and, either a value is returned or no value at all), the promise returned from then is considered resolved. You have to return a rejected promise from each error handler in order to propagate and chain error handlers.
For example:
promseA.then(
function success() {
},
function error() {
return $q.reject();
})
.promiseB.then(
function success() {
},
function error() {
return $q.reject();
})
.promiseC.then(
function success() {
},
function error() {
return $q.reject();
});

Michael Kang
- 52,003
- 16
- 103
- 135
-
3When a rejected promise has an rejection handler that promise still stays rejected since promises never transition once they resolved. The _returned promise_ from the thenable chaining is resolved _if the value returned from the promise error handler is not a rejected promise_ – Benjamin Gruenbaum Apr 13 '15 at 10:11
-
I think we are saying the same thing. When I said "the promise is considered resolved, I was actually referring to the promise returned from the then call. However, my wording could be clearer... – Michael Kang Apr 13 '15 at 10:18
-
Thanks for clarifying, found a duplicate but good answer now nontheless. – Benjamin Gruenbaum Apr 13 '15 at 10:28
-
1@pixelbits, `return $q.reject()` is indeed a better option than `throwing`, but maybe you could add this option to your answer as well so that OP if sees this technique will recognize it. – Max Koretskyi Apr 13 '15 at 11:13
0
then
/fail
function returns a promise, which can be rejected by throwing errors. If you want to chain multiple error handlers and trigger them all you should throw error from preceding error handlers.
var d = $q.defer();
d.promise.catch(errorHandler1).catch(errorHandler2);
d.reject();
function errorHandler1 {
throw new Error();
}
function errorHandler2() {
console.log("I am triggered");
}
Or instead of catch
, you can use then
method and pass errorHandler1
and errorHandler2
as a second parameter.

Max Koretskyi
- 101,079
- 60
- 333
- 488
-
3This will log an error to `$exceptionHandler` in Angular, also I don't think this is what OP wants. – Benjamin Gruenbaum Apr 13 '15 at 10:10
-
Right, I didn't know that there is such option `return $q.reject();`. It's much better then throwing an error. Is this also standard for `Q` library and not only angular's `$q`? – Max Koretskyi Apr 13 '15 at 11:11
-
3In Q it's perfectly fine to `throw` since the $exceptionHandler hack does not exist - although you should really not be using Q in new code anymore. – Benjamin Gruenbaum Apr 13 '15 at 11:12
-
_although you should really not be using Q in new code anymore_ - do you mean in angular code? – Max Koretskyi Apr 13 '15 at 11:14
-
No, I mean in general, it's a really old and outdated promise library. Take a look at bluebird for a much much better alternative. (Other alternatives such as When and RSVP are also decent, also - promises are native now anyway) – Benjamin Gruenbaum Apr 13 '15 at 11:15
-
I see, thanks. `Q` is using `Promises/A+` standard as well as native implementations, so I guess the overall approach will be the same, right? Is returning a rejected promise is also `Promises/A+` standard? – Max Koretskyi Apr 13 '15 at 11:20
-
3Yes, returning a rejected promise behaving this way is a requirement of the Promises/A+ standard. It will behave consistently across all Promises/A+ implementations. – Benjamin Gruenbaum Apr 13 '15 at 11:22
-
Thanks, do you know where I can read about when to use throwing or return rejected promise in non-angular applications – Max Koretskyi Apr 13 '15 at 11:29
-
No, but this is literally all there is to it: Throwing and rejecting do the same thing, except `throw`ing will also call `$exceptionHandler` where rejecting will not. This is the code: https://github.com/angular/angular.js/blob/v1.4.0-rc.0/src/ng/q.js#L321-L324 – Benjamin Gruenbaum Apr 13 '15 at 11:30