Can't throw error from asynchronous promise fulfillment function

I am trying to get a conceptual understanding of why the following code is not catching throw

. If you remove the keyword async

from the part new Promise(async (resolve, ...

, then it works great, so it has to do with the Promise executor being an asynchronous 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 reiterate that "if you use any other asynchronous callback you should use reject

", but by "asynchronous" they do not apply to functions async

, so I don't think their explanations apply here (and if they they will do it, I do not understand how).

If throw

used instead reject

, the above code works fine. I would like to understand, in principle, why throw

it doesn't work here. Thank!


source to share

1 answer

This is the async / Promise

version of the antipattern constructor !

Never ever used async function

as an executor functionPromise

(even when you can make it work 1 )!

[1: by calling resolve

and reject

instead of using the return

and operators throw


by "asynchronous" they don't refer to functions async

, so I don't think their explanations apply here

They could too. A simple example where it cannot work is

new Promise(async function() {
    await delay(…);
    throw new Error(…);


which is equivalent

new Promise(function() {
    return delay(…).then(function() {
        throw new Error(…);


where it is now clear what throw

is inside the async callback.

The constructor Promise

can only catch synchronous exceptions, it async function

never throws - it always returns a promise (which can be rejected though). And that return value is ignored as the promise is pending resolve




All Articles