The Node.js Error Model
Why It Matters
Node.js applications fail through thrown exceptions, rejected promises, callback errors, event emitter errors, process signals, and external system failures. Understanding the error model helps you decide what to handle, what to retry, and what should crash fast.
Core Concepts
- Synchronous code throws exceptions with
throw. - Promise-based code fails by rejecting.
- Older callback APIs usually pass
erroras the first callback argument. - Event emitters may emit an
errorevent that must be handled. - Operational errors are expected runtime failures; programmer errors are bugs.
Flow to Remember
An error occurs, the current async boundary determines how it is delivered, application code classifies it, and either handles it locally, forwards it to error middleware, or lets the process fail under supervision.
Syntax and Examples
import { readFile } from 'node:fs/promises';
import { EventEmitter } from 'node:events';
try {
const config = await readFile('missing.json', 'utf8');
console.log(config);
} catch (error) {
if (error.code === 'ENOENT') {
console.error('Config file is missing');
} else {
throw error;
}
}
const worker = new EventEmitter();
worker.on('error', (error) => {
console.error('Worker failed', error);
});Use Cases and Tradeoffs
- Handle expected operational errors near the code that can recover.
- Let unexpected programmer errors surface loudly in development.
- Use structured custom errors for domain failures.
- Run production processes under a supervisor that restarts crashed services.
Common Mistakes
- Catching every error and continuing in an unknown state.
- Treating rejected promises like synchronous exceptions without
awaitor.catch(). - Forgetting
errorlisteners on emitters that can fail. - Logging only
error.messageand losing stack/context.
Practical Challenge
Write examples of the same file-not-found failure using sync throw, promise rejection, and callback-style error handling. Decide where each should be handled.
Recap
- Node has multiple error delivery mechanisms.
- Operational errors and programmer errors deserve different responses.
- Errors should keep context without leaking secrets.