JavaScript AggregateError: What It Is and When It Occurs

The AggregateError object in JavaScript is a built-in error type designed to represent multiple errors wrapped into a single unified exception. This article provides a clear guide on what AggregateError is, its core properties, and the exact scenarios where JavaScript generates or utilizes it, particularly during concurrent asynchronous operations and batch processing.

What is the AggregateError Object?

Introduced in ECMAScript 2021 (ES12), AggregateError is a subclass of the standard Error object. While standard error objects capture a single failure point, AggregateError allows multiple distinct error instances to be grouped and thrown together as one event.

An AggregateError instance includes standard error properties alongside a specialized errors property:

When is AggregateError Generated?

JavaScript generates or uses AggregateError in two primary contexts: natively via Promise.any() and manually through custom application logic.

1. Natively with Promise.any()

The primary native source of an AggregateError is Promise.any().

Promise.any() accepts an iterable of promises and resolves as soon as the first promise fulfills. If all passed promises reject, Promise.any() rejects with an AggregateError containing the rejection reasons from every promise in its errors property.

const promise1 = Promise.reject(new Error("Database connection failed"));
const promise2 = Promise.reject(new Error("API endpoint timed out"));
const promise3 = Promise.reject(new Error("Cache unavailable"));

Promise.any([promise1, promise2, promise3])
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    if (error instanceof AggregateError) {
      console.error(error.message); // "All promises were rejected"
      
      // Iterate over each individual rejection reason
      for (const individualError of error.errors) {
        console.error(individualError.message);
      }
    }
  });

2. Manual Instantiation for Batch Operations

Developers can explicitly instantiate an AggregateError when performing operations where multiple independent failures should be collected before throwing an error, rather than failing on the very first issue.

Common use cases include: * Form or Schema Validation: Validating multiple fields at once and reporting all validation failures together. * Batch File Processing: Attempting to process multiple files in parallel and returning all individual read/write failures at the end. * Task Runners: Running a series of setup tasks where inspecting every failure is necessary for debugging.

function validateUserData(user) {
  const errors = [];

  if (!user.username) {
    errors.push(new Error("Username is required."));
  }
  if (!user.email || !user.email.includes("@")) {
    errors.push(new Error("A valid email address is required."));
  }
  if (user.age < 18) {
    errors.push(new Error("User must be at least 18 years old."));
  }

  if (errors.length > 0) {
    throw new AggregateError(errors, "User validation failed.");
  }

  return true;
}

try {
  validateUserData({ username: "", email: "invalid-email", age: 16 });
} catch (err) {
  if (err instanceof AggregateError) {
    console.error(err.message); // "User validation failed."
    err.errors.forEach((e) => console.error(`- ${e.message}`));
  }
}

Summary

The AggregateError object solves the challenge of handling multiple concurrent failures in JavaScript. It is automatically thrown when all inputs to Promise.any() fail, and it serves as the standard structure whenever custom logic requires bundling several errors into a single throwable exception.