Handling Errors and Exceptions
1. Using Try-Catch Blocks
Example
try {
const data = JSON.parse(input);
} catch (err) {
if (err instanceof SyntaxError) return defaultValue;
throw err;
}
2. Handling Async Errors
| Pattern | Notes |
try { await x } catch | Idiomatic |
.catch(handler) | Promise chain |
Forgotten await | Becomes unhandled rejection |
3. Creating Custom Errors
Example
class HttpError extends Error {
constructor(status, message, opts) {
super(message, opts);
this.name = "HttpError";
this.status = status;
}
}
throw new HttpError(404, "user not found", { cause: dbErr });
Note: { cause } chains errors v16.9+; visible in stack output.
4. Using Error Stack Traces (error.stack)
| Property | Use |
error.stack | String trace |
Error.stackTraceLimit = 50 | Increase frames captured |
--stack-trace-limit=N | CLI equivalent |
5. Using Error Codes (error.code)
| Code | Domain |
ENOENT | File not found |
EACCES | Permission denied |
EADDRINUSE | Port in use |
ECONNREFUSED | Connection refused |
ERR_INVALID_ARG_TYPE | Bad argument |
6. Using Error.captureStackTrace
Example
class AppError extends Error {
constructor(msg) {
super(msg);
Error.captureStackTrace(this, AppError); // hide constructor frame
}
}
7. Handling Uncaught Exceptions
Example
process.on("uncaughtException", (err, origin) => {
logger.fatal({ err, origin });
process.exit(1); // exit; let supervisor restart
});
Warning: Don't continue after uncaughtException — process state may be corrupt.
8. Handling Unhandled Rejections
| API | Use |
process.on("unhandledRejection", h) | Last-resort handler |
--unhandled-rejections=strict | Crash on unhandled (default since v15) |
9. Implementing Error Middleware
Example: Express style
app.use((err, req, res, next) => {
const status = err.status ?? 500;
res.status(status).json({ error: { code: err.code, message: err.message } });
});
10. Using Domain Module
| Status | Detail |
| DEPRECATED | Replaced by AsyncLocalStorage + structured error handling |
11. Graceful Error Recovery
| Strategy | Use |
| Circuit breakers | Stop cascading failures (e.g., opossum) |
| Retry with backoff | Transient errors only |
| Bulkheads | Isolate resources per dependency |
| Timeouts | Bound every external call |
12. Logging Errors
| Practice | Detail |
| Structured | JSON, with err code/stack |
| Include cause chain | Walk err.cause |
| Don't log secrets | Redact tokens, PII |
| Send to APM | Sentry, Datadog, NewRelic |