Home > database >  promise got resolved instead of rejected, even the inner promise returned
promise got resolved instead of rejected, even the inner promise returned

Time:11-07

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).

  • Related