©
本文档使用 PHP中文网手册 发布
以与其他中间件功能相同的方式定义错误处理中间件函数,但错误处理函数有四个参数而不是三个:(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()
代码中的错误,即使自定义错误处理中间件已就位,也可以触发默认错误处理程序。