This document might be outdated relative to the documentation in English. For the latest updates, please refer to the documentation in English.

Error handling

Define error-handling middleware like other middleware, except with four arguments instead of three, specifically with the signature (err, req, res, next)):

app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

You define error-handling middleware last, after other app.use() and routes calls; For example:

const bodyParser = require('body-parser')
const methodOverride = require('method-override')

app.use(bodyParser())
app.use(methodOverride())
app.use((err, req, res, next) => {
  // logic
})

Responses from within the middleware are completely arbitrary. You may wish to respond with an HTML error page, a simple message, a JSON string, or anything else you prefer.

For organizational (and higher-level framework) purposes, you may define several error-handling middleware, much like you would with regular middleware. For example suppose you wanted to define an error-handler for requests made via XHR, and those without, you might do:

const bodyParser = require('body-parser')
const methodOverride = require('method-override')

app.use(bodyParser())
app.use(methodOverride())
app.use(logErrors)
app.use(clientErrorHandler)
app.use(errorHandler)

Where the more generic logErrors may write request and error information to stderr, loggly, or similar services:

function logErrors (err, req, res, next) {
  console.error(err.stack)
  next(err)
}

Where clientErrorHandler is defined as the following (note that the error is explicitly passed along to the next):

function clientErrorHandler (err, req, res, next) {
  if (req.xhr) {
    res.status(500).send({ error: 'Something blew up!' })
  } else {
    next(err)
  }
}

The following errorHandler “catch-all” implementation may be defined as:

function errorHandler (err, req, res, next) {
  res.status(500)
  res.render('error', { error: err })
}