Using AggregateError in JavaScript
See Multiple Errors in One Error
📚 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 AggregateError
is 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.