这个翻译StrongLoop / IBM提供.

相对于英文版的文档,本文档可能已过时。要了解最近的更新,请参阅英文版文档

错误处理

错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个:(err, req, res, next):例如:

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

请在其他 app.use() 和路由调用之后,最后定义错误处理中间件,例如:

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

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

中间件函数中的响应可以采用您首选的任何格式,例如,HTML 错误页、简单消息或 JSON 字符串。

出于组织(和更高级框架)的目的,可以定义若干错误处理中间件函数,这和对常规中间件函数的处理很相似。例如,如果您希望为使用 XHR 发出的请求以及未使用此对象发出的请求定义错误处理程序,可以使用以下命令:

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)

在此示例中,通用 logErrors 可能将请求和错误信息写入 stderr,例如:

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

也是在此示例中,clientErrorHandler 定义如下,错误会显式传递到下一项:

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

“catch-all”errorHandler 函数可以如下实现:

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

如果将任何项传递到 next() 函数(除了字符串 'route'),那么 Express 会将当前请求视为处于错误状态,并跳过所有剩余的非错误处理路由和中间件函数。如果您希望以某种方式处理此错误,必须如下一节中所述创建一个错误处理路由。

如果一个路由处理程序具有多个回调函数,那么可以使用 route 参数跳至下一个路由处理程序。例如:

app.get('/a_route_behind_paywall',
  (req, res, next) => {
    if (!req.user.hasPaid) {

      // continue handling this request
      next('route')
    }
  }, (req, res, next) => {
    PaidContent.find((err, doc) => {
      if (err) return next(err)
      res.json(doc)
    })
  })

在此示例中,将跳过 getPaidContent 处理程序,而将继续执行 /a_route_behind_paywallapp 中所有剩余的处理程序。

next()next(err) 的调用会表明当前处理程序是否完整以及处于何种状态。next(err) 将跳过链中所有剩余的处理程序(设置为按上述方式处理错误的处理程序除外)。

缺省错误处理程序

Express 随附一个内置的错误处理程序,负责处理应用程序中可能遇到的任何错误。这个缺省的错误处理中间件函数添加在中间件函数集的末尾。

如果将错误传递到 next() 且未在错误处理程序中进行处理,那么该错误将由内置的错误处理程序处理;错误将写入客户机的堆栈跟踪内。堆栈跟踪不包含在生产环境中。

将环境变量 NODE_ENV 设置为 production,以生产方式运行此应用程序。

如果在开始写响应之后调用 next() 时出错(例如,如果在以流式方式将响应传输到客户机时遇到错误),Express 缺省错误处理程序会关闭连接并使请求失败。

因此,在添加定制错误处理程序时,如果头已发送到客户机,您可能希望委托给 Express 中的缺省错误处理机制处理:

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