捕获Node js app的所有uncaughtException

Nam*_*anh 22 node.js express

我有一个问题:如何为我的节点应用程序处理所有未被捕获的异常(操作/开发人员错误将关闭所有服务).然后,只要发现错误,我就可以向我发送电子邮件提醒.

Dar*_*rio 47

您可以使用流程 ' uncaughtException'和' unhandledRejection'事件.

还要记住,在' ' 之后恢复正常操作是不安全uncaughtException的,因为系统已损坏:

正确使用' uncaughtException'是在关闭进程之前执行已分配资源(例如文件描述符,句柄等)的同步清理.

例:

process
  .on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
    process.exit(1);
  });
Run Code Online (Sandbox Code Playgroud)

  • 可以,但不应该。请参阅@xShirase 的回答。 (2认同)

xSh*_*ase 10

您可以使用域API:https://nodejs.org/api/domain.html 但它已被弃用,无论如何都不推荐.

通常,您希望在可能发生的任何地方处理错误,并避免采用"全部捕获"方法.

如果发生错误,忽略它就没有动力去解决它,在某些情况下可能导致你甚至不知道你的程序出现故障.

相反,处理它的最好方法是让程序崩溃,记录崩溃(和堆栈/核心转储),然后使用pm2或nodemon自动重启它.

对于Joyent(节点创建者)的(非常)长但有见地的演讲,我强烈建议您阅读此链接:Node.JS中的错误处理

还有一个process.on('uncaughtException')事件(你也不应该使用)

编辑:更多细节和尝试解决您的问题.使用像pm2这样的软件在崩溃时重新启动应用程序,您还可以看到error.log,它将为您提供堆栈跟踪.因此,似乎您仍然需要的唯一事情是警报崩溃.

为此,你可能想看看keymetrics(制作pm2的同一个人)之类的接口,这些接口可能会提醒你错误.

很久很久以前我使用过的很酷的解决方案如下:

  • 当您的应用程序(重新)启动时,它会查找错误日志
  • 如果找到一个,它会提醒您日志文件的内容
  • 然后它将错误日志文件重命名/移动到其他位置

我不需要推荐这个解决方案,但它符合您需要的所有规格,所以玩得开心!

编辑2:如果您想深入研究服务开发和最佳实践的主题,请在评论中查看@Paul建议的链接:https://12factor.net/

  • 另外值得注意的是节点遵循unix原则,这意味着每个应用程序都应该做好一件事.如果在应用崩溃时想要发送电子邮件,那么这超出了应用范围.相反,你崩溃(并记录)为@xShirase说,然后有其他东西(例如systemd或logwatch)注意到这一点并在达到阈值时发送电子邮件(即使该阈值是"任何错误"). (2认同)

小智 6

最好的方法是让应用程序崩溃,记录错误,然后重新启动进程。你可以像这样简单地做到这一点

var cluster = require('cluster');

var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; ++i) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  var http = require('http');
  var httpServer = http.createServer(app).listen(httpPort, function () {
      console.log('process id local', process.pid)
      console.log("http server started at port " + httpPort);
  });
}

process.on('uncaughtException', function (err) {
  console.error((new Date).toUTCString() + ' uncaughtException:', err.message)
  console.error(err.stack)
  process.exit(1)
})
Run Code Online (Sandbox Code Playgroud)

`