捕获 Node js 应用程序的所有未捕获异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40867345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:50:48  来源:igfitidea点击:

Catch all uncaughtException for Node js app

node.jsexpress

提问by Nam Tran Thanh

I have a question: how do I can handle all uncaught Exception (operations/developer error will take all service down) for my node app. Then I can send an email alert to me whenever catch an error.

我有一个问题:如何处理我的节点应用程序的所有未捕获的异常(操作/开发人员错误将关闭所有服务)。然后我可以在发现错误时向我发送电子邮件警报。

回答by Dario

You can use process'uncaughtException' and 'unhandledRejection' events.

您可以使用进程uncaughtException”和“ unhandledRejection”事件。

Also remember that it is not safe to resumenormal operation after 'uncaughtException', because the system becomes corrupted:

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

The correct use of 'uncaughtException' is to perform synchronous cleanup of allocated resources (e.g. file descriptors, handles, etc) before shutting down the process.

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

Example:

例子:

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);
  });

回答by xShirase

You could use the Domain API : https://nodejs.org/api/domain.htmlBut it is deprecated and not recommended anyway.

您可以使用域 API:https: //nodejs.org/api/domain.html但它已被弃用,也不推荐使用。

In general, you want to handle errors anywhere they may occur and avoid a "catch all" approach.

一般而言,您希望在可能发生的任何地方处理错误,并避免“一网打尽”的方法。

If an error occurs, ignoring it is no incentive to fix it, and in some cases could lead to you not even knowing that your program is malfunctioning.

如果发生错误,忽略它并不是修复它的动力,并且在某些情况下可能导致您甚至不知道您的程序出现故障。

Instead, the best way to handle it is to have your program crash, log the crash (and the stack/core dump), then restart it automatically, using pm2 or nodemon.

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

For a (very) long but insightful speech by Joyent (Node creators), I strongly recommend you read this link : Error handling in Node.JS

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

There's also a process.on('uncaughtException')event (that you should also not use)

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

Edit:A bit more details and an attempt at solving your issue. Using a software like pm2 to restart your app on crash, you will also be able to see the error.log, which will give you the stack trace. So it seems that the only thing you still need is to be alerted of the crash.

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

For that, you may want to have a look at interfaces like keymetrics (same guys who made pm2) which potentially could alert you on errors.

为此,您可能需要查看 keymetrics(制作 pm2 的同一个人)之类的接口,它们可能会提醒您出现错误。

A cool solution I used once, a long long time ago was as follows :

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

  • when your app (re)starts, it looks for an error log
  • If it finds one, it alerts you with the content of the log file
  • it then renames/move the error logfile to a different location
  • 当您的应用(重新)启动时,它会查找错误日志
  • 如果找到,它会用日志文件的内容提醒您
  • 然后将错误日志文件重命名/移动到不同的位置

I wouldn't necessary recommend this solution, but it fits all the specs you need, so have fun with it!

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

Edit2 : If you feel like delving deeper into the topics of service development and best practices, have a look at his link suggested by @Paul in the comments : https://12factor.net/

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

回答by Suman

the best way is to let the application crash, log the error and then restart the process. you can do it simply like this

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

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)
})

`

`