Skip to content
UniCircle
MediumConceptualExpress

Error-handling middleware in Express

Question NODE-EXP-002

How do you write error-handling middleware in Express? Where must it be placed, and how do you make errors from async route handlers reach it?

Show the explanation

Model answer. Express recognises error handlers by their four parameters: (err, req, res, next). Register it after all routes and other middleware, because errors travel forward from where they happen.

JavaScript
app.get('/orders/:id', async (req, res, next) => {
  try {
    const order = await db.findOrder(req.params.id);
    if (!order) return res.status(404).json({ error: 'Order not found' });
    res.json(order);
  } catch (err) {
    next(err);                       // hand it to the error handler
  }
});

app.use((req, res) => res.status(404).json({ error: 'No such route' }));   // 404 last but one
app.use((err, req, res, next) => {                                       // error handler last
  console.error(err);
  const status = err.status || 500;
  res.status(status).json({ error: status === 500 ? 'Something went wrong' : err.message });
});

Points interviewers look for:

  • So if there are five middlewares, the error handler is the last one.
  • In Express 4, a rejected promise in an async handler is not caught automatically: use try/catch + next(err), or a wrapper. Express 5 forwards rejected promises for you.
  • Do not leak stack traces or internal messages to clients in production; log them on the server.

Original UniCircle question. Last reviewed 22 Oct 2026.