1

Running the code

Promise.all(new Promise((res, rej) => rej('Failure!')))
.catch(() => console.log("It's all okay."))

in Node v12.19.0 logs It's all okay. to the console but still throws an exception. Why is that? I would have expected the same behaviour as when I run

new Promise((res, rej) => rej('Failure!'))
.catch(() => console.log("It's all okay."))

This will also log It's all okay. to the console but does not throw an exception.

How can I catch the rejection in Promise.all()?

Full console output:

> Promise.all(new Promise((res, rej) => rej('Failure!'))).catch(() => console.log("It's all okay."))
Promise { <pending> }
> It's all okay.
(node:2872) UnhandledPromiseRejectionWarning: Failure!
(node:2872) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)

> new Promise((res, rej) => rej('Failure!')).catch(() => console.log("It's all okay."))
Promise { <pending> }
> It's all okay.
OliverRM
  • 43
  • 6
  • 5
    The argument to `Promise.all()` should be an array of promises, not a single promise. – Barmar Mar 22 '21 at 15:33
  • 1
    `Promise.all(ARRAY_OF_PROMISE_HERE)` – hackape Mar 22 '21 at 15:33
  • Thanks. My assumption that `Promise.all(promise1, promise2, ...)` should work was wrong. But why than does it fire the catch on rejection even if its not an array? – OliverRM Mar 22 '21 at 16:12
  • 1
    Maybe use `.catch((err) => console.log(err))` instead of saying that "*It's all okay.*" :-P – Bergi Mar 22 '21 at 16:25
  • The unhandled rejection comes from the `new Promise((res, rej) => rej('Failure!'))` which is not handled anywhere, not from the `Promise.all()` (which you *did* handle). – Bergi Mar 22 '21 at 16:27

1 Answers1

2

As pointed out by Bergi in the comments...

If you execute your first bit of code without the catch statement (or actually print the errors you catch) you'll see what is happening.

Promise.all(new Promise((res, rej) => rej('Failure!')))

Returns:

Promise {<rejected>: TypeError}
Uncaught (in promise) Failure!
Uncaught (in promise) TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
    at Function.all (<anonymous>)
    at <anonymous>:1:9

Notice the first error is the error we throw by rejecting the promise.

The second error comes from not using Promise.all() correctly, which is the error you were catching.

The error we throw by rejecting the promise is never caught because of the incorrect usage of the Promise.all() method.


Now, let's test out the code with our promise inside an array, which is the correct usage of Promise.all(), as pointed out by Barmar in the comments.

Promise.all([new Promise((res, rej) => rej('Failure!'))])
    .catch(() => console.log("It's all okay."))

Returns:

Promise {<fulfilled>}
It´s all okay.

So, we are successfully catching the rejected promise error.

Also worth noting, the final promise returned is the promise that the catch() method returns after execution. Which is fulfilled since we successfully executed the catch statement, although the promise that Promise.all() actually returns is rejected.