JavaScriptError HandlingIntermediate

Error.cause (chained errors)

Allows associating a new error with an underlying original error, creating a chain of errors for better debugging context.

Review the syntaxStudy the examplesOpen the coding app
new Error(message, { cause: originalError })

This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.

What it does

Overview

Allows associating a new error with an underlying original error, creating a chain of errors for better debugging context.

The `Error.cause` property, introduced in ES2022, provides a standardized and highly beneficial way to chain errors. This feature is particularly useful when you catch an error at a lower level of abstraction (e.g., a database error, a network error) and then throw a new, more specific, or higher-level error that wraps the original one. By passing an object `{ cause: originalError }` as the second argument to the `Error` constructor, you can link the new error to the exception that directly caused it. This creates a clear lineage of errors, making it much easier to trace the root cause of a problem through multiple layers of abstraction or function calls. Instead of losing the context of the initial error (which often happens when simply re-throwing a new error), `Error.cause` preserves it, significantly improving debugging efforts and error logging. It's a best practice to use `Error.cause` when re-throwing errors with additional context, as it provides a structured and discoverable way to access the full error history, unlike manually attaching arbitrary properties to error objects, which can be inconsistent.

Quick reference

Syntax

new Error(message, { cause: originalError })

Inputs

Parameters

message (optional)String · A human-readable description of the new error.
options.cause (optional)Error | Any · The underlying error that caused the current error. Can be any value, but typically an `Error` object.

See it in practice

Examples

1

Wrapping a low-level error with a high-level one

function fetchUser(userId) {
  try {
    // Simulate a network failure
    throw new TypeError('Failed to fetch: Network unreachable');
  } catch (networkErr) {
    throw new Error(`Could not retrieve user ${userId}.`, { cause: networkErr });
  }
}

try {
  fetchUser('abc-123');
} catch (appError) {
  console.error(`Application Error: ${appError.message}`);
  console.error(`  Caused by: ${appError.cause.name}: ${appError.cause.message}`);
}
Output:
Application Error: Could not retrieve user abc-123. Caused by: TypeError: Failed to fetch: Network unreachable

A generic `Error` is thrown, but it wraps the original `TypeError` using `cause`. This allows the top-level `catch` to present a user-friendly message while still having access to the detailed underlying error for debugging.

2

Chaining multiple errors

function parseConfig(jsonString) {
  try {
    return JSON.parse(jsonString);
  } catch (jsonErr) {
    throw new Error('Invalid configuration format.', { cause: jsonErr });
  }
}

function loadApplication(configPath) {
  try {
    // Simulate reading a file that's not valid JSON
    const rawConfig = '{ "key": "value"'; // Malformed JSON
    return parseConfig(rawConfig);
  } catch (configErr) {
    throw new Error(`Failed to load application configuration from ${configPath}.`, { cause: configErr });
  }
}

try {
  loadApplication('/app/config.json');
} catch (finalError) {
  console.error(`Top-level Error: ${finalError.message}`);
  let current = finalError;
  while (current.cause) {
    current = current.cause;
    console.error(`  Caused by: ${current.name || 'Error'}: ${current.message}`);
  }
}
Output:
Top-level Error: Failed to load application configuration from /app/config.json. Caused by: Error: Invalid configuration format. Caused by: SyntaxError: Expected '}' after property list in JSON at position 16

This example demonstrates a chain of three errors: a `SyntaxError` from `JSON.parse`, wrapped by an 'Invalid configuration' error, which is then wrapped by a 'Failed to load application' error. The loop iterates through the `cause` property to reveal the full chain.

3

Accessing `Error.cause` in custom error classes

class DataAccessError extends Error {
  constructor(message, options) {
    super(message, options);
    this.name = 'DataAccessError';
  }
}

function queryDatabase() {
  try {
    throw new Error('SQL connection failed.');
  } catch (dbError) {
    throw new DataAccessError('Failed to access database.', { cause: dbError });
  }
}

try {
  queryDatabase();
} catch (err) {
  console.error(`Error: ${err.name}: ${err.message}`);
  if (err.cause) {
    console.error(`  Original cause: ${err.cause.name}: ${err.cause.message}`);
  }
}
Output:
Error: DataAccessError: Failed to access database. Original cause: Error: SQL connection failed.

Custom error classes can also leverage `Error.cause` by passing the `options` object to `super()`. This allows for type-specific error handling while still preserving the original cause.

Debug faster

Common Errors

1

Forgetting the `{ cause: ... }` object syntax

Cause: Passing the `cause` directly as a third argument or as part of the message string, rather than within the `options` object as `{ cause: originalError }`.

Fix: Ensure that the `cause` is always provided as a property of the second argument (the options object) to the `Error` constructor: `new Error(message, { cause: originalError })`.

const original = new Error('Original');
// new Error('New error', original); // Incorrect syntax, original will be ignored
const newError = new Error('New error', { cause: original }); // Correct

Runtime support

Compatibility

Node.js 16.9+, Deno 1.13+All modern (Safari 15.4+, Chrome 93+, Firefox 91+)ES2022

Source: MDN Web Docs

Common questions

Frequently Asked Questions

Allows associating a new error with an underlying original error, creating a chain of errors for better debugging context.

message: A human-readable description of the new error. options.cause: The underlying error that caused the current error. Can be any value, but typically an `Error` object.

Forgetting the `{ cause: ... }` object syntax: Ensure that the `cause` is always provided as a property of the second argument (the options object) to the `Error` constructor: `new Error(message, { cause: originalError })`.