在线文档教程

5.错误处理 | 5. Error handling

错误处理

以与其他中间件功能相同的方式定义错误处理中间件函数,但错误处理函数有四个参数而不是三个:(err, req, res, next)。例如:

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

您最后定义错误处理中间件,在其他app.use()路由之后并路由呼叫; 例如:

var bodyParser = require('body-parser') var methodOverride = require('method-override') app.use(bodyParser.urlencoded{ extended: true })) app.use(bodyParser.json()) app.use(methodOverride()) app.use(function (err, req, res, next) { // logic })

来自中间件功能的响应可以采用任何您喜欢的格式,例如HTML错误页面,简单消息或JSON字符串。

对于组织(和更高级别的框架)目的,您可以定义几个错误处理中间件函数,就像使用常规中间件函数一样。例如,如果您想要为使用XHR和不使用的请求定义错误处理程序,则可以使用以下命令:

var bodyParser = require('body-parser') var methodOverride = require('method-override') app.use(bodyParser.urlencoded{ extended: true })) app.use(bodyParser.json()) 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定义如下:在这种情况下,错误会显式传递给下一个错误。

请注意,如果不在错误处理函数中调用“next”,则需要负责编写(并结束)响应。否则,这些请求将“挂起”并且不符合垃圾回收的条件。

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', function checkIfPaidSubscriber (req, res, next) { if (!req.user.hasPaid) { // continue handling this request next('route') } else{ next( } }, function getPaidContent (req, res, next) { PaidContent.find(function (err, doc) { if (err) return next(err) res.json(doc) }) })

在这个例子中,getPaidContent处理程序将被跳过,但在任何剩余处理app时将继续要执行/a_route_behind_paywall

调用next()next(err)指出当前处理程序已完成并处于何种状态。next(err)将会跳过链中所有剩余的处理程序,除了那些设置为处理错误的处理程序,如上所述。

默认错误处理程序

Express带有一个内置的错误处理程序,它处理应用程序中可能遇到的任何错误。这个默认的错误处理中间件功能被添加到中间件功能堆栈的末尾。

如果你传递一个错误next()并且你没有在错误处理器中处理它,它将由内置的错误处理器来处理; 该错误将通过堆栈跟踪写入客户端。生产环境中不包含堆栈跟踪。

production设置环境变量ODE_ENV,运行在生产模式下的应用程序。

如果您调用next()响应后发生错误(例如,如果在将响应传输到客户端时遇到错误),Express默认错误处理程序将关闭连接并使请求失败。

因此,当您添加自定义错误处理程序时,您将希望在头文件已经发送到客户端时委派到Express中的默认错误处理机制:

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

请注意,如果您多次调用next()代码中的错误,即使自定义错误处理中间件已就位,也可以触发默认错误处理程序。