Chapter 12: Node.js Error Handling

Error Handling in Node.js — written as if I’m sitting next to you, showing code on the screen, explaining decisions, common traps, production patterns, and real-world trade-offs.

Let’s go step by step — from basic mistakes to professional-level patterns used in 2025–2026.

1. Why error handling in Node.js is surprisingly tricky

Node.js has two completely different worlds of errors:

World Type of code How errors are reported Must catch them?
Synchronous code Normal function calls, loops, calculations Thrown exceptions (throw new Error()) Yes — try/catch
Asynchronous code callbacks, promises, async/await Usually not thrown — passed or rejected Yes — special care

Most beginners only learn how to catch synchronous errors and then get surprised when:

  • the server crashes on unhandled promise rejections
  • async route handlers silently fail
  • errors disappear in .then() chains

Goal of good Node.js error handling:

  • Never crash the process in production (unless catastrophic)
  • Always log meaningful information
  • Always respond to the client with proper HTTP status + message
  • Never leak sensitive information (stack traces, DB credentials…)

2. Synchronous error handling (easy part)

JavaScript

Rule of thumb for sync code:

→ Always wrap risky operations in try/catch

3. Asynchronous error handling – three eras

A. Callback style (old but still everywhere)

JavaScript

Pattern: if (err) return … is very common in callback code

B. Promise style – classic mistake

JavaScript

Correct minimum:

JavaScript

C. async / await style – the modern standard (2025–2026)

JavaScript

Golden rule for async/await:

Always wrap the whole async function body in try/catch → Or make sure every await is inside some try/catch

4. Express.js – most common real-world case

Wrong way (very common beginner code)

JavaScript

→ Unhandled rejection → process crashes (Node 15+ shows warning, later versions crash)

Correct way – pattern used in serious projects

JavaScript

Why this pattern is so popular:

  • Every async route is automatically protected
  • One central place for logging & formatting errors
  • No need to repeat try/catch in every route
  • Clean HTTP responses even when things break

5. Recommended error types / classes (production style)

JavaScript

Benefits:

  • You can check err.isOperational to decide whether to send message to client
  • Clear distinction between bugs and expected failures

6. Quick reference – Where to catch errors

Place / Situation Where to catch / handle Pattern / Tool
Sync functions try/catch Standard
Promise chains .catch() at the end .catch(err => …)
async / await functions try/catch around await calls Recommended
Express async routes asyncHandler wrapper or global error middleware Very common in production
Unhandled promise rejections process.on(‘unhandledRejection’, …) Must have in production
Uncaught exceptions process.on(‘uncaughtException’, …) Last resort – usually log & exit
Top-level startup code Top-level try/catch or .catch() main().catch(err => …)

Summary – Rules of thumb (2025–2026 style)

  1. Always use try/catch in async functions or asyncHandler wrapper in Express
  2. Never leave promises without .catch() or await in try/catch
  3. Always have a global error handler in Express/Fastify/Hono
  4. Log meaningful context (request url, user id, error code…)
  5. Never send stack traces to clients in production
  6. Use custom error classes (AppError, ValidationError, AuthError…) for better control
  7. Listen for unhandled rejections — even if you think you caught everything

Would you like to go deeper into any part?

  • Full production-ready Express error handling boilerplate
  • Custom error classes + status codes mapping
  • Handling errors in Prisma / Mongoose / TypeORM
  • Graceful shutdown on uncaught errors
  • Logging best practices (Winston, Pino, structured logging)
  • Testing error handling (supertest + custom errors)

Just tell me which direction feels most useful right now — I’ll continue with concrete code examples. 😄

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *