How To Properly Handle Errors in Promise.all?

September 22, 2019
Thomas Duffy

Written by Thomas Duffy

promise.all error handling

Promise.all is an awesome way to handle multiple promises in parallel. What most people don’t realize is that handling errors with Promise.all is not as straight forward as it seems. In this post we’ll explore the gotchas when handling errors while using Promise.all.

Refresher on Promise.all

Promise.all is method that takes in an array of promises and returns a single promise once they’re all resolved.

Promise.all is useful for situations where you need the result of multiple async actions before performing a given task.

A common use case is when you need to operate on multiple datasets at the same time coming from different network requests.

Below is an example of how Promise.all works.

const firstPromise = Promise.resolve(‘first-promise’);
const secondPromise = Promise.resolve(‘second-promise’);
const thirdPromise = Promise.resolve(‘third-promise’);

const completeResult = Promise.all([firstPromise, secondPromise, thirdPromise]).then((result) => {
  conosle.log(result)
});

// Output: [‘first-promise’, ‘second-promise’, ‘third-promise’]

The Gotcha with Promise.all

The Gotcha that most people don’t realize with Promise.all is what happens when one of the multiple promises being executed reject. Let’s take a look at an example.

const firstPromise = Promise.resolve(‘first-promise’);
// Rejected promise
const secondPromise = Promise.reject(‘failed’);
const thirdPromise = Promise.resolve(‘third-promise’);

const completeResult = Promise.all([firstPromise, secondPromise, thirdPromise]).then((result) => {
  conosle.log(result)
}).catch((error) => {
   console.log(error)
});

// Output of Promise.all: ‘failed’

As you can see from the example above, if anyone of the promises passed into Promise.all rejects, then the whole Promise.all will reject.

Basically it’s an all or none type of situation. Obviously this can be problematic if you still wanted to operate any of the data from the resolved promises. Let’s take a look at how to get around this issue.

The work around.

const firstPromise = Promise.resolve(‘first-promise’).catch(() => ‘error’);
const secondPromise = Promise.reject(‘failed’).catch(() => ‘error’);
const thirdPromise = Promise.resolve(‘third-promise’).catch(() => ‘error’);

const completeResult = Promise.all([firstPromise, secondPromise, thirdPromise]).then((result) => {
  conosle.log(result)
})


// Output: [‘first-promise’, ‘error’,’second-promise ’]

From the example above you can see that all we have to do is add a catch statement to each promise we pass into the Promise.all. If any of the promises reject, they’ll be resolved through the catch statement chained to the specific promise.

Recap of the solution

If you are using Promise.all but don’t necessarily need all the promises passed in to resolve to perform your operation, then you need to handle each promise’s exception separately. On the other hand, If you are in another all or nothing type of situation, you can let the error propagate to the Promise.all catch statement and reject everything.


Thomas Duffy

Written by Thomas Duffy