Remove the async
from the new Promise( async function( ...))
and it works as expected. That async
is catching the exception and turning it into a rejected promise which the promise is not expecting. It is not part of the contract with the new Promise()
constructor that you pass it a function that returns a promise that it should pay attention to.
Instead, the Promise constructor catches synchronous exceptions in the executor function or waits for you to call the resolve()
or reject()
callbacks and pays zero attention to whatever is returned from the executor callback function.
You can see here that if you remove the async
keyword, then it works as expected and the exception is caught in the .catch()
.
function test() {
return new Promise(function( resolve, reject ) {
objectThatDoesntExist.property = 1;
} );
}
test().catch( (error) => { console.log("Caught " + error) } );
Note: One might ask "why" the Promise constructor doesn't support the case when it's made async
. It seems like a promise-friendly thing to do. I don't know the actual logic that went into the decision not to support that, but I do know that whenever you're using async
inside a new Promise()
executor function, that's typically a sign that you don't need the new Promise()
wrapper at all. If you're using async
for a reason, then you already have promises. If you already have promises, then you typically don't need to wrap it in new Promise()
as you can use/return the promises you already have.