Photo by Autumn Mott Rodeheaver on Unsplash

Using AggregateError in JavaScript

See Multiple Errors in One Error

Faraz Kelhini
3 min readOct 29, 2021

--

📚 Connect with us. Want to hear what’s new at The Pragmatic Bookshelf? Sign up for our newsletter. You’ll be the first to know about author speaking engagements, books in beta, new books in print, and promo codes that give you discounts of up to 40%.

Besides the Error constructor, JavaScript provides a set of subclasses that we can use to indicate particular types of errors. These subclasses are SyntaxError, TypeError, URIError, RangeError, ReferenceError, and EvalError. ES2021 adds one more subclass to this list: AggregateError.

AggregateError is designed to represent multiple errors in a single object. In situations where multiple errors are possible, like a user input form, it makes sense to group errors. That way you can throw a single error that represents all of the errors instead of one for each invalid input.

A built-in JavaScript method that takes advantage of AggregateError is Promise.any(). This method, which is also a ES2021 feature, enables us to request data from multiple APIs and use the result of the first successful promise.

When all of the input promises passed to Promise.any() fail, the method rejects with an AggregateError object. Consider this example:

const promises = [
Promise.reject(new Error('failure #1')),
Promise.reject(new Error('failure #2')),
Promise.reject(new Error('failure #3'))
];
Promise.any(promises).then(
(result) => console.log(result),
(error) => console.error(error)
);
// logs:
// => AggregateError: No Promise in Promise.any was resolved

💡 Support for AggregateError is still spotty and limited to very recent browsers. So, before running the examples, you may want to ensure
your browser supports it
.

AggregateError groups the errors of all input promises into a single error object. The object holds several properties. To access the rejection reason for each promise, we’ll need to read the errors property of the object:

const promises = [
Promise.reject(new Error('failure #1')),
Promise.reject(new Error('failure #2')),
Promise.reject(new Error('failure #3'))
];
Promise.any(promises).catch(error => {
console.log(error.name);
console.log(error.message);
console.log(error.errors);
});

This code prints the following message in the browser’s console showing all the rejection reasons:

💡 If you’d like to learn more about Promise.any(), pick up Modern Asynchronous JavaScript, which details all sorts of examples and patterns.

If you want to group your program’s errors into one single error similar to Promise.any(), you can use the AggregateError constructor. Let’s see how it works:

const myError = new AggregateError([
new TypeError('The first argument must be a number'),
new RangeError('The first argument must be between 1 to 10'),
new URIError('The second argument is not a valid URL'),
], 'The operation failed')

Here, we create an instance of AggregateError and pass an array of errors to it. We then assign the instance to myError. Now, throwing myError gets us the following information:

try {
throw myError;
} catch (error) {
console.log(error.name);
console.log(error.message);
console.log(error.errors);
}

The AggregateErroris extremely useful when the possibility of multiple errors is likely. Take advantage of the AggregateError subclass to make your JavaScript more efficient.

If you enjoyed this article, you may also like Faraz Kelhini’s book, Modern Asynchronous JavaScript, now out in beta. Through October 31, 2021, you can use promo code fkajs_medium_35 to save 35% on the ebook version. Promo codes are not valid on prior purchases.

--

--

Faraz Kelhini

Faraz is a professional JavaScript developer who is passionate about promoting patterns and ideas that make web development more productive. Website: eloux.com