Important things to understand here
Both the then
and catch
functions return new promise objects.
Either throwing or explicitly rejecting, will move the current promise to the rejected state.
Since then
and catch
return new promise objects, they can be chained.
If you throw or reject inside a promise handler (then
or catch
), it will be handled in the next rejection handler down the chaining path.
As mentioned by jfriend00, the then
and catch
handlers are not executed synchronously. When a handler throws, it will come to an end immediately. So, the stack will be unwound and the exception would be lost. That is why throwing an exception rejects the current promise.
In your case, you are rejecting inside do1
by throwing an Error
object. Now, the current promise will be in rejected state and the control will be transferred to the next handler, which is then
in our case.
Since the then
handler doesn't have a rejection handler, the do2
will not be executed at all. You can confirm this by using console.log
inside it. Since the current promise doesn't have a rejection handler, it will also be rejected with the rejection value from the previous promise and the control will be transferred to the next handler which is catch
.
As catch
is a rejection handler, when you do console.log(err.stack);
inside it, you are able to see the error stack trace. Now, you are throwing an Error
object from it so the promise returned by catch
will also be in rejected state.
Since you have not attached any rejection handler to the catch
, you are not able to observe the rejection.
You can split the chain and understand this better, like this
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
The output you will get will be something like
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
Inside the catch
handler 1, you are getting the value of promise
object as rejected.
Same way, the promise returned by the catch
handler 1, is also rejected with the same error with which the promise
was rejected and we are observing it in the second catch
handler.