Home > Web Front-end > JS Tutorial > A Hidden Gem in JavaScript Debugging: error.cause

A Hidden Gem in JavaScript Debugging: error.cause

DDD
Release: 2025-01-12 16:45:47
Original
750 people have browsed it

A Hidden Gem in JavaScript Debugging: error.cause

The Challenges of Debugging

What is the biggest challenge in debugging? One of them is undoubtedly tracing the source of errors.

Imagine this scenario:

const func = () => {
  doSth('A');
  doSth('B');
};
Copy after login
Copy after login

When func throws an error, how do you identify at which step the error occurred? Was it caused by doSth('A'), doSth('B'), or func itself? Clearly, the error lacks sufficient context.

Common Solutions

A common approach to address this issue might look like this:

const func = () => {
  try {
    doSth('A');
  } catch (error) {
    throw new Error('An error from A', error);
  }
  try {
    doSth('B');
  } catch (error) {
    throw new Error('An error from B', error);
  }
};
Copy after login
Copy after login

With this approach, you can locate the source of the error more easily. However, this solution has several limitations:

  1. Loss of error details:

    If the error contains extensive information (e.g., payloads, HTTP status codes, error codes), this approach only adds the error message of doSth to the newly constructed error. Other crucial details, including the original stack trace, are lost.

  2. Decreased log readability:

    With more than two potential error points, the logs can become cluttered and difficult to interpret.

  3. Ambiguity in expressing intent:

    The code does not explicitly communicate that the new error is caused by the specific doSth function being caught, leaving room for improved code readability.

Introducing error.cause

To address these issues, ECMAScript 2022 introduced error.cause.

This feature allows developers to specify the root cause of an error when creating a new error object. By using error.cause, you can establish a chain of errors, making it easier to debug and trace the root cause of an issue.

Here’s a simple example:

try {
  // Some operation that may throw an error
} catch (error) {
  throw new Error('Something went wrong', { cause: error });
}
Copy after login

With this approach, you can build causal links between errors. For instance:

const func = () => {
  try {
    doSth('A');
  } catch (error) {
    throw new Error('An error from A', { cause: error });
  }
  try {
    doSth('B');
  } catch (error) {
    throw new Error('An error from B', { cause: error });
  }
};
Copy after login

This allows us to catch errors thrown by lower-level functions (e.g., doSth('A')), throw a new error that adds relevant context (e.g., "An error occurred while executing doSth('A')"), and preserve the original error details (e.g., "A is an illegal argument.").

Building a Chain of Errors

Another advantage of error.cause is its ability to create a chain of linked errors, enabling developers to trace issues back through multiple layers of the application:

const func = () => {
  try {
    try {
      try {
        doSth('A');
      } catch (error) {
        throw new Error('Error at depth 3', { cause: error });
      }
    } catch (error) {
      throw new Error('Error at depth 2', { cause: error });
    }
  } catch (error) {
    throw new Error('Error at depth 1', { cause: error });
  }
};

console.log(error.cause.cause); // Error at depth 3
Copy after login

In Node.js, errors with a cause are handled specially in the console. All related error stacks are printed:

const func = () => {
  doSth('A');
  doSth('B');
};
Copy after login
Copy after login

Conclusion

  • Debugging becomes significantly easier when you have immediate access to both the error context and details.
  • One effective way to achieve this is by adopting a "catch rethrow with context" pattern using the error.cause feature:
const func = () => {
  try {
    doSth('A');
  } catch (error) {
    throw new Error('An error from A', error);
  }
  try {
    doSth('B');
  } catch (error) {
    throw new Error('An error from B', error);
  }
};
Copy after login
Copy after login

This approach not only improves error traceability but also enhances the readability and maintainability of your code.


We are Leapcell, your top choice for deploying Node.js projects to the cloud.

A Hidden Gem in JavaScript Debugging: error.cause

Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:

Multi-Language Support

  • Develop with Node.js, Python, Go, or Rust.

Deploy unlimited projects for free

  • pay only for usage — no requests, no charges.

Unbeatable Cost Efficiency

  • Pay-as-you-go with no idle charges.
  • Example: $25 supports 6.94M requests at a 60ms average response time.

Streamlined Developer Experience

  • Intuitive UI for effortless setup.
  • Fully automated CI/CD pipelines and GitOps integration.
  • Real-time metrics and logging for actionable insights.

Effortless Scalability and High Performance

  • Auto-scaling to handle high concurrency with ease.
  • Zero operational overhead — just focus on building.

Explore more in the Documentation!

A Hidden Gem in JavaScript Debugging: error.cause

Follow us on X: @LeapcellHQ


Read on our blog

The above is the detailed content of A Hidden Gem in JavaScript Debugging: error.cause. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template