for the following promise chain
new Promise(r=>r('b').then(()=>Promise.reject('x'))).catch(err=>console.log({error}))
the inner promise is returned, so it should bubble up and catched by the outer catch
block and logs the error to the console.
but instead, it got resolved.
Promise {<fulfilled>: 'b'}
how to catch the inner promise by an outer catch block?
CodePudding user response:
r
(more typically called resolve
) does not return a promise, so calling .then
on it is an error. Normally, if an error is thrown in a promise executor function (the function you pass new Promise
), the promise being created is rejected with that error. But since you've already called resolve
, you've fulfilled the promise with "b"
, and once fulfilled it cannot be changed to being rejected, so the error occurring during the executor is just suppressed. (This is a specific case of the more general rule that once a promise is resolved [tied to an outcome] it can't be resolved differently. A promise can be resolved without [yet] being fulfilled, but fulfilling it is one way of resolving it. If you're not 100% on this promise terminology, check out my blog post here explaining it.)
If you want to resolve the promise you're creating to another promise, you pass it into the resolve
function:
new Promise(resolve => {
resolve(Promise.reject(new Error("x")));
})
.then(value => console.log("value", value))
.catch(error => console.error("error", error.message));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
That specific example would be an example of the Explicit promise construction antipattern (we should just use the promise from Promise.reject
directly), but if you had branching logic in the promise executor and some of the branches didn't involve promises, you might do something similar to this (though stylistically it would make more sense to me to throw an error or call the reject
function passed to the executor).