What is good error handling?
Good error handling decides what happens when something goes wrong: which errors you recover from, which you surface to the client, and what you record for yourself. Logging is the other half — leaving a trail detailed enough to explain a failure you did not witness.
Why it matters
In production you do not watch requests happen; you read about them afterward in
logs. A service with vague errors and console.log everywhere is nearly
impossible to debug at 2am. Structured, leveled logs and clear error types are
what let you find the one failing request among millions.
What to learn
- Throwing and catching, and where to put the boundary
- Custom error classes and error codes
- Operational vs programmer errors
- Failing fast vs degrading gracefully
- Structured logging with levels and JSON output
- Correlation ids to trace one request across logs
- Not leaking stack traces or secrets to clients
Common pitfall
Swallowing errors with an empty catch block, or logging and then continuing as
if nothing happened. The failure disappears, the data is half-written, and the
next bug is impossible to trace. Either handle an error meaningfully or let it
propagate to a boundary that does.
Resources
Primary (free):
- Node.js — Error handling guide · docs
- MDN — Error · docs
- Pino — logging docs · docs
Practice
Add a central error handler to your Node server. Define a custom error class with a status code, throw it from a route on bad input, and have the handler log a structured JSON line with a request id and return the right status. Confirm a thrown error never crashes the process or leaks a stack trace to the client.
Outcomes
- Distinguish operational errors from programmer bugs.
- Define custom error types that carry a status code.
- Emit structured, leveled logs instead of bare console output.
- Trace a single failing request using a correlation id.