Error Handling & Debugging
Robust error handling is what separates amateur applications from production-ready systems. In this chapter, you’ll learn how to handle errors gracefully, debug effectively, and implement logging strategies.
Understanding Error Types
Operational vs Programming Errors
Critical Distinction: Operational errors should be handled. Programming errors should crash the app (in production, use a process manager to restart).
The Error Class
Every error in JavaScript inherits from the built-in Error class. When you create an error, Node.js automatically captures a stack trace — a breadcrumb trail showing exactly which functions were called and in what order leading up to the error. This stack trace is your most valuable debugging tool.
Custom Error Classes
Async Error Handling Patterns
Callbacks (Legacy)
Promises
Async/Await
Express Error Handling
Centralized Error Handler
404 Handler
Global Error Handlers
These are your application’s last line of defense — safety nets that catch errors which slipped through every other handler. In a well-designed app, these should rarely fire. If they fire frequently, you have unhandled errors upstream that need fixing.
Think of these like the emergency shutoff on a factory machine: you hope they never activate, but when they do, they prevent catastrophic damage.
Production tip: Always run your Node.js process behind a process manager like PM2 or inside a container orchestrator. When process.exit(1) fires, the manager automatically restarts the process, minimizing downtime. Without a process manager, your app just stays dead after a crash.
Debugging Techniques
Console Methods
Node.js Debugger
VS Code Debugging
Logging with Winston
console.log is fine during development, but in production you need structured, level-based logging that can write to files, external services, or monitoring platforms. Winston is the most widely used logging library in the Node.js ecosystem. It separates the concept of what you log (levels and messages) from where it goes (transports like console, files, or cloud services).
HTTP Request Logging with Morgan
Structured Logging
Summary
- Distinguish between operational and programming errors
- Create custom error classes for different error types
- Use async wrappers to catch errors in async routes
- Implement a centralized error handler in Express
- Handle uncaught exceptions and unhandled rejections
- Use Winston for structured, configurable logging
- Debug with VS Code or Chrome DevTools
- Log meaningful context with each error