What is AggregateError?
Managing multiple concurrent operations that can fail in different ways is a common challenge in modern web development. AggregateError provides an elegant solution by wrapping multiple errors in a single error object, allowing you to handle several failures at once rather than dealing with them one at a time.
Introduced in ES2021 (ECMAScript 2021), AggregateError is a built-in JavaScript object that represents several errors needing to be reported by an operation. It extends the base Error class, so it inherits all Error properties and methods while adding the ability to contain multiple individual errors.
Why AggregateError Matters
Before AggregateError, developers had to create custom error objects or use workarounds to collect and report multiple failures. With modern applications making numerous concurrent API calls and processing batch operations, having a standard way to represent multiple errors has become essential for robust error handling in JavaScript applications. When working with AI-powered automation workflows that process multiple data streams, AggregateError helps you capture and respond to all failures systematically.
Constructor and Syntax
The AggregateError constructor follows a straightforward pattern that accepts an iterable of errors and optional message and configuration parameters.
Constructor Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
errors | Iterable | Yes | An iterable of errors - can be Error instances or any values |
message | string | No | Human-readable description of what went wrong |
options | object | No | Configuration object with cause property |
Basic Syntax
// Basic usage
new AggregateError(errors)
// With message
new AggregateError(errors, "Operation failed with multiple errors")
// With cause for error chaining
new AggregateError(errors, "Batch processing failed", { cause: originalError })
The constructor can be called with or without the new keyword - both approaches create a valid AggregateError instance.
Working with AggregateError Instances
When you catch an AggregateError, you have access to all standard Error properties plus the additional errors array that contains the aggregated failures.
Instance Properties
| Property | Type | Description |
|---|---|---|
errors | Error[] | Array containing all the aggregated errors |
message | string | The error message (inherited from Error) |
name | string | Always "AggregateError" (inherited from Error) |
cause | unknown | The underlying cause if provided (inherited from Error) |
Accessing Individual Errors
try {
// code that throws AggregateError
} catch (error) {
if (error instanceof AggregateError) {
console.log(`Total failures: ${error.errors.length}`);
error.errors.forEach((err, index) => {
console.log(`Error ${index + 1}:`, err.message);
});
}
}
The errors array maintains the original order of the errors as they were provided to the constructor, allowing you to trace back each failure to its source operation.
Practical Use Cases
Promise.any() Integration
The most common built-in use of AggregateError is with Promise.any(). When all promises passed to Promise.any() reject, it throws an AggregateError containing all the rejection reasons:
const endpoints = [
fetch('/api/data1'),
fetch('/api/data2'),
fetch('/api/data3')
];
try {
const result = await Promise.any(endpoints);
console.log('First successful response:', result);
} catch (error) {
if (error instanceof AggregateError) {
console.log(`${error.errors.length} requests failed`);
error.errors.forEach(err => console.error(err.message));
// Display user-friendly summary
showUserFeedback(`${error.errors.length} endpoints are currently unavailable`);
}
}
Batch Processing Validation
When processing a batch of items where each operation can fail independently, AggregateError lets you collect all failures and report them comprehensively:
async function processBatch(items) {
const errors = [];
for (const item of items) {
try {
await processItem(item);
} catch (error) {
errors.push(new Error(`Item ${item.id}: ${error.message}`));
}
}
if (errors.length > 0) {
throw new AggregateError(
errors,
`Failed to process ${errors.length} items out of ${items.length}`
);
}
}
Form Validation
AggregateError excels at collecting multiple validation errors before presenting them to users:
function validateForm(formData) {
const errors = [];
if (!formData.email || !formData.email.includes('@')) {
errors.push(new Error('Please enter a valid email address'));
}
if (!formData.password || formData.password.length < 8) {
errors.push(new Error('Password must be at least 8 characters'));
}
if (formData.password !== formData.confirmPassword) {
errors.push(new Error('Passwords do not match'));
}
if (errors.length > 0) {
throw new AggregateError(errors, 'Please fix the following issues');
}
}
Browser Support and Compatibility
AggregateError is part of the Baseline "widely available" set of features, meaning it works across all modern browsers:
| Browser | Version | Release Date |
|---|---|---|
| Chrome | 85+ | September 2020 |
| Firefox | 79+ | July 2020 |
| Safari | 14+ | September 2020 |
| Edge | 85+ | September 2020 |
Polyfills for Legacy Environments
For applications that need to support older browsers, polyfills are available:
- core-js: The comprehensive polyfill library includes AggregateError support
- es-aggregate-error: A focused polyfill package for just AggregateError
// Using core-js
import 'core-js/stable/aggregate-error';
// Using the focused polyfill
import AggregateError from 'es-aggregate-error';
When using polyfills, ensure they load before any code that uses AggregateError to prevent runtime errors.
Best Practices
When to Use AggregateError
- Multiple independent operations that can fail separately
- Collecting all failures before making decisions on how to proceed
- Providing comprehensive error information to users or logging systems
When NOT to Use AggregateError
- Causally related errors - use error chaining with the
causeproperty instead - Single error scenarios - use a regular Error object
- Performance-critical paths with potentially large error sets
Error Message Design
Craft clear, actionable error messages that summarize the aggregate while providing actionable guidance:
// Good: Specific and informative
throw new AggregateError(
errors,
`Failed to import ${errors.length} records. Please review the errors below.`
);
// Avoid: Vague messages
throw new AggregateError(errors, 'Error');
Limiting Error Counts
For operations that could potentially generate hundreds of errors, consider capping the collection to prevent memory issues:
const MAX_ERRORS = 100;
const errors = collectedErrors.slice(0, MAX_ERRORS);
if (collectedErrors.length > MAX_ERRORS) {
errors.push(new Error(
`... and ${collectedErrors.length - MAX_ERRORS} more errors (not shown)`
));
}
throw new AggregateError(
errors,
`Processing failed with ${collectedErrors.length} total errors`
);
Error Handling Patterns
Comprehensive Catching
Handle AggregateError alongside regular errors in a production-ready pattern:
async function robustOperation() {
try {
await riskyOperation();
} catch (error) {
if (error instanceof AggregateError) {
// Handle multiple errors with context
logAggregateError(error);
displayMultipleErrors(error.errors);
} else if (error instanceof Error) {
// Handle single error
logError(error);
displaySingleError(error);
}
}
}
User-Friendly Error Presentation
Transform technical AggregateError instances into user-friendly feedback:
function presentErrors(error) {
if (error instanceof AggregateError) {
const messages = error.errors.map(err => err.message);
return {
title: 'Multiple Issues Found',
message: `Please fix the following ${messages.length} issues:`,
details: messages.map(m => `- ${m}`).join('\n')
};
}
return {
title: 'An Error Occurred',
message: error.message
};
}
Related JavaScript Features
- Promise.allSettled(): Returns an array of result objects for each promise, avoiding AggregateError but requiring manual iteration
- Error cause chain: Use the
causeproperty when you need to preserve the original error chain - Custom error types: Extend Error or AggregateError for domain-specific error hierarchies
For more on building robust JavaScript applications with proper error handling, explore our web development services.
Frequently Asked Questions
Sources
- MDN Web Docs - AggregateError - Comprehensive documentation on AggregateError syntax, properties, and usage
- MDN Web Docs - AggregateError() constructor - Constructor parameters and usage patterns
- TC39 ECMAScript Specification - Official language specification defining AggregateError behavior