Overview

7 Errors

```html

JavaScript errors are presented as a simple feature, but in practice they are shaped by implementation details, runtime conventions, and a long history of engine-specific behavior. The chapter explains that errors are useful for two very different purposes: applications need concise signals for recovery, while developers need rich diagnostic detail for debugging. Because those goals demand different information, error handling in JavaScript becomes a balance between preserving enough context to understand failures and keeping the runtime cost of that context under control.

The text distinguishes between ordinary thrown values and standardized Error objects, then shows how modern error features improve both recovery and debugging. Native error types like TypeError and RangeError mainly describe language-rule violations, while newer additions such as AggregateError, SuppressedError, and the cause property preserve more meaningful failure chains. The chapter also highlights host-specific systems such as DOMException and Node.js error codes, which give machines stable identifiers for recovery while leaving human-readable messages for developers.

A major theme is that stack traces are invaluable but expensive: they consume memory, take time to capture, and become even costlier when serialized or repeated at scale. Error propagation is shown as a control-flow process where throw moves an error up the call stack until a matching handler is found, so placement of handlers matters. Best results come from catching errors at semantic boundaries such as transactions, API calls, or resource cleanup, while global handlers remain only a last-resort safety net. The chapter ends by stressing that asynchronous boundaries break ordinary try-catch behavior, so error handling must adapt when work is scheduled to run later.

```

Summary

  • JavaScript allows throwing any value, but Error objects with stack traces are the standard convention for providing both recovery information and debugging context.
  • Native error types like TypeError and RangeError describe language violations but provide no recovery guidance. Modern additions like AggregateError and DOMException types address specific failure scenarios more meaningfully.
  • The cause property enables error wrapping at boundaries, preserving complete debugging context while presenting clean recovery information at each layer.
  • Node.js error codes separate machine-readable recovery mechanisms from human-readable debugging messages, preventing brittle error message parsing.
  • Stack traces capture the function call chain for debugging but carry significant memory and performance costs. Engines optimize through lazy serialization and configurable depth limits.
  • Error propagation through try-catch works by unwinding the call stack frame by frame until a handler is found or the application crashes.
  • Place catch handlers at semantic boundaries—transaction, API, resource, or user operation boundaries—where you have context for both recovery decisions and debugging detail.
  • Finally blocks guarantee cleanup execution but can suppress or replace errors, breaking both recovery and debugging if return statements or throws are used carelessly.
  • Asynchronous operations like setTimeout break the call stack, preventing try-catch from catching errors and leaving incomplete stack traces that lack scheduling context.
  • Global error handlers (window.error, process.uncaughtException) catch errors that escape all try-catch handlers but are too far from error context for effective recovery or debugging.
  • When errors regularly reach global handlers, it signals missing error handling at proper boundaries. Global handlers should be a safety net, not a primary strategy.
  • The async boundary problem requires different error handling mechanisms explored in Chapter 8, where Promises and async/await provide error propagation that works across async operations.

FAQ

What is the main purpose of errors in JavaScript?Errors serve two different needs: recovery for the application and debugging for the developer. The application usually needs only enough information to decide whether to retry, fallback, or abort, while the developer needs detailed context like stack traces, line numbers, and messages.
Why are JavaScript errors considered more complex than the language specification suggests?The specification mainly defines Error as an object with name and message, but real-world errors also involve stack traces, error codes, engine-specific behavior, runtime differences, and even thrown values that are not Error objects at all.
Can JavaScript throw values other than Error objects?Yes. JavaScript allows throwing any value, including strings, numbers, null, undefined, and arbitrary objects. However, modern code usually throws Error objects because they provide more useful structure and debugging information.
What are the native JavaScript error types?The built-in error constructors include Error, SyntaxError, ReferenceError, TypeError, RangeError, URIError, EvalError, AggregateError, and SuppressedError. The first seven are the most commonly used.
What is AggregateError used for?AggregateError is used when multiple failures happen at once, especially with Promise.any(). It wraps multiple individual errors in one object so you can inspect all the reasons the attempts failed.
What is the purpose of the cause property on errors?The cause property lets you wrap one error inside another while preserving the original failure context. This is useful at boundaries where you want a clean, user-safe error message but still keep detailed internal debugging information.
Why are stack traces expensive in JavaScript?Stack traces are captured when an Error is created, which requires collecting structured frame information. They cost memory and CPU even if the stack is never read, and serializing the stack to a string adds more overhead when accessed.
Why should error handlers be placed at semantic boundaries?Semantic boundaries like transactions, API calls, user actions, and resource cleanup provide the right balance of context for both recovery and debugging. Catching too early loses recovery context, while catching too late loses useful details about what failed.
Why can’t try-catch handle errors inside setTimeout() callbacks?Because asynchronous callbacks run on a new call stack after the original try-catch has already finished. The error is thrown later, in a different execution context, so the original handler cannot catch it.
What role do global error handlers play in JavaScript?Global handlers like window.onerror and Node.js uncaughtException are a last resort for logging and monitoring uncaught errors. They are not a substitute for proper handling at semantic boundaries because they usually lack the local context needed for good recovery decisions.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • JavaScript in Depth ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • JavaScript in Depth ebook for free