Clean Markup

Chaining Contextual Exceptions with JavaScript Error Cause

Chaining Contextual Exceptions with JavaScript Error Cause

In layered application architectures—such as API clients, database access layers, and UI state managers—catching a low-level error (e.g. TypeError: Failed to fetch) and rethrowing a high-level domain error (e.g. UserNotFoundError) historically erased the original stack trace and error message.

ES2022 introduced the cause property to the Error constructor, allowing developers to chain contextual errors while preserving full causal stack traces.

Example

async function fetchUserProfile(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return await response.json();
  } catch (err) {
    throw new Error(`Failed to load profile for user ${userId}`, { cause: err });
  }
}

Implementation

Logging the top-level error retains the full diagnostic ancestry:

try {
  await fetchUserProfile('user_42');
} catch (error) {
  console.error(error.message);       // "Failed to load profile for user user_42"
  console.error('Caused by:', error.cause); // Original network error or HTTP status
}

Main Point: The Error({ cause }) feature enables clean layered error handling without destroying diagnostic stack traces.

Credits

Photo by Kalist Strzalkowski on Unsplash

← Home