0

到目前为止,我已经检查了以通用方式处理 promise 的错误,unhandledRejection 事件处理程序是最好的方法。就像下面这样:

process.on('unhandledRejection', (reason,promise) => {
console.log('error: unhandledRejection');
});

现在,当我想访问此事件处理程序中的请求和响应对象时,挑战就来了。这样我就可以以通用方式生成 500 响应,因此我不需要在项目的任何地方添加承诺异常处理。

我被建议使用:

app.use(function (req, res, next) {
process.on('unhandledRejection', function (reason,promise) {
console.error("Here I can access request objects.")
// Unregister unhandledRejection
});
});

但在上述情况下,事件监听器将被注册多次,并且只有在发生异常时才会取消注册。由于事件会被多次注册,所以code( console.error("Here I can access request objects."))会被多次触发。

有什么建议么 ?如果我可以访问 app.use 之外的请求和响应对象?

提前致谢!

4

1 回答 1

0

默认情况下,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-routerexpress-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');
});
于 2021-03-02T16:43:28.070 回答