Skip to the solution
MediumLow-Level Design7 min read

How do you handle errors in Node.js applications?

668 views

The problem

Question presented to candidate: "An async Express route handler throws an error with no try/catch around it. What happens to that request, and does your answer change between Express 4 and Express 5?"

What a strong answer should cover:

  • Node.js error handling is not one mechanism β€” it differs by context: synchronous code uses try/catch; callback-style async code uses the error-first (err, result) convention; Promise-based/async code uses try/catch around await, or .catch().
  • πŸ“Œ A version-specific, verifiable gap: in Express 4, a synchronous throw inside a route handler is automatically caught and routed to centralized error-handling middleware β€” but an async handler that throws (or rejects) with no manual next(err) call is not caught automatically; it crashes the process as an uncaught exception. Express 5 fixes this specific gap, automatically forwarding a rejected promise from an async handler to next().
  • Centralized error-handling middleware in Express is a 4-argument function (err, req, res, next) β€” Express recognizes this specific arity and routes errors to it, distinct from ordinary 3-argument middleware.
  • The operational vs. programmer error distinction (covered fully in its own dedicated question) determines the right response once an error is caught: an operational error should be handled and answered with an appropriate status code; a programmer error/bug should generally be logged and allowed to crash the process for a supervisor to restart, rather than papered over.
  • uncaughtException/unhandledRejection handlers at the process level are a last-resort safety net β€” logging and exiting β€” not a substitute for handling errors correctly at the point they actually occur.
  • A precise answer names the practical mitigation for the Express-4 async gap specifically: wrap every async handler in a small utility (a manual try/catch calling next(e), or a wrapper like express-async-handler) until/unless the codebase is on Express 5.

Clarifying questions expected:

  • "Which Express major version, or a different framework entirely?" β€” the async-handler auto-catch behavior is genuinely version-dependent, verified above.
  • "Is the concern about a specific caught error's response, or the broader process-level safety net?" β€” these are different layers of the same overall topic.

Code / implementation expected: Yes β€” actually demonstrating the Express 4 async-handler gap (a real crash) versus the manual-next(e) fix is the concrete, convincing part of the answer.

  • error handling
  • asynchronous
  • promises
  • best practices

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

7 min read Β· 9 sections

Read the code

JavaScriptA real Express 4 server: sync throw auto-caught, async+next(e) forwarded correctly, unhandled async throw crashes the process
const express = require("express");
const app = express();

app.get("/sync-throw", (req, res) => { throw new Error("sync error"); });

app.get("/async-throw-manual", async (req, res, next) => {
  try { throw new Error("async error"); } catch (e) { next(e); }
});

app.get("/async-unhandled", async (req, res) => {
  throw new Error("unhandled async error"); // Express 4: NOT caught, crashes the process
});

app.use((err, req, res, next) => { // 4 args = error middleware, recognized by arity
  res.status(500).json({ error: err.message });
});

// sync-throw               -> 500 { error: "sync error" }
// async-throw-manual       -> 500 { error: "async error" }
// async-unhandled          -> process CRASHES (Express 4 has no auto-catch here)

// The fix, until on Express 5:
const wrap = (fn) => (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
app.get("/safe", wrap(async (req, res) => { throw new Error("now correctly forwarded"); }));

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 77 of 152 in Node.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Node.js questions
Up nextMedium

What is the perf_hooks module and how do you measure performance?

Continue