CodePark/ questions / HTTP servers & Express middleware
START PRACTICINGPRACTICE
Backend question · Node.js › HTTP servers & Express middleware

How does error-handling middleware work in Express?

app.use((err, req, res, next) => {
  if (res.headersSent) return next(err);
  const status = err.status ?? 500;
  res.status(status).json({ message: status < 500 ? err.message : "Internal error" });
});

Error-handling middleware is a function with four parameters: (err, req, res, next). Express recognizes it by its arity, which means the number of declared parameters. So you must declare all four, even if you do not use next. You register it with app.use, after all routes and other middleware.

Express runs the error handlers when a middleware or handler does one of these:

  • Calls next(err).
  • Throws an error synchronously (not inside a callback or promise).

Then Express skips the remaining normal middleware and runs the error handlers in order. An error handler can send the response. Or it can call next(err) to pass the error to the next error handler.

If no custom handler responds, Express's default handler responds. It uses err.status (or err.statusCode) when that is a 4xx or 5xx code, and 500 otherwise. In development, the response includes the stack trace.

Sometimes the headers were already sent, for example in the middle of streaming a response. Check res.headersSent. If it is true, call next(err) so the default handler can close the connection.

  • An error handler has four parameters (err, req, res, next), and Express detects it by arity.
  • You register error handlers after the routes.
  • next(err) or a synchronous throw triggers them.
  • An error handler can pass the error on with next(err).
  • If res.headersSent is true, pass the error to the default handler.