默认情况下,express 会处理错误。通过快递文件:
Express 带有一个嵌入式错误处理程序,它将处理应用程序中可能发生的任何错误。这个默认的错误处理中间件函数被添加到中间件函数栈的末尾。
next() 如果你给函数一个错误并且不在自定义错误处理程序中处理它,这个错误由嵌入的错误处理程序处理;错误通过堆栈跟踪打印在客户端上。堆栈跟踪不包含在生产环境中。
将环境变量的 NODE_ENV 值设置为生产,以在生产模式下运行应用程序。
打印错误时,会将以下信息添加到响应中:
res.statusCode err.status 字段的值来自该字段(或 err.statusCode)。如果此值不在 4xx 或 5xx 的范围内,则将其设置为 500。
res.statusMessage 字段根据状态码设置。
如果在生产模式下,正文(body)成为状态码消息的 HTML,否则为 err.stack。
err.headers 对象中指定的任何标头。
next() 如果在开始写入响应后调用函数出错(例如,如果在向客户端传输响应时遇到错误),默认的 Express 错误处理程序将关闭连接并使请求失败。
添加自定义错误处理程序时,如果标头已发送到客户端,则应授权默认 Express 错误处理程序:
function errorHandler (err, req, res, next) {
if (res.headersSent) {
return next(err)
}
res.status(500)
res.render('error', { error: err })
}
多次调用 next() 函数并在代码中出现错误可能会触发默认错误处理程序,即使自定义错误处理程序中间件已到位。
这很容易发生内存泄漏:
app.use(function (req, res, next) {
process.on('unhandledRejection', function (reason,promise) {
console.error("这里我可以访问请求对象。") // 注销 unhandledRejection
}); } );
此外,您无法访问“unhandledRejection”中的响应对象,如果 express 可以处理您向用户发送“500”状态代码,您为什么要访问该对象。随时随地捕捉承诺始终是一个好习惯。但是,如果某些承诺仍未涵盖,那么也有一些库可以处理它,例如:express-promise-router,express-async-errors
我们可以在 express 错误处理程序中使用 err 参数发出有意义的错误响应,并将响应发送给用户。例如,
app.use((err, req, res, next) => {
if (err.name === 'CustomError' && err.message === 'EmptyResponse') {
return res.status(404).send('Not Found');
}
// ... more error cases...
return res.status(500).send('Internal Server Error');
});