I've been trying to get a conceptual understanding of why the following code doesn't catch the throw
. If you remove the async
keyword from the new Promise(async (resolve, ...
part then it works fine, so it has to do with the fact that the Promise executor is an async function.
(async function() {
try {
await fn();
} catch(e) {
console.log("CAUGHT fn error -->",e)
}
})();
function fn() {
return new Promise(async (resolve, reject) => {
// ...
throw new Error("<<fn error>>");
// ...
});
}
The answers here, here, and here repeat that "if you're in any other asynchronous callback, you must use reject
", but by "asynchronous" they're not referring to async
functions, so I don't think their explanations apply here (and if they do, I don't understand how).
If instead of throw
we use reject
, the above code works fine. I'd like to understand, fundamentally, why throw
doesn't work here. Thanks!
This is the async/await version of the
Promise
constructor antipattern!Never ever use an
async function
as aPromise
executor function (even when you can make it work1)![1: by calling
resolve
andreject
instead of usingreturn
andthrow
statements]They could as well. A simple example where it cannot work is
which is equivalent to
where it's clear now that the
throw
is inside an asynchronous callback.The
Promise
constructor can only catch synchronous exceptions, and anasync function
never throws - it always returns a promise (which might get rejected though). And that return value is ignored, as the promise is waiting forresolve
to be called.