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

Node.js 捕获节点js应用程序的所有未捕获异常,node.js,express,Node.js,Express,我有一个问题:如何处理我的节点应用程序的所有未捕获异常(操作/开发人员错误将关闭所有服务)。然后,我可以在发现错误时向我发送电子邮件警报。您可以使用域API: 但它已被弃用,无论如何也不推荐使用 一般来说,您希望在任何可能发生错误的地方处理错误,并避免“一网打尽”的方法 如果发生错误,忽略它并不是修复它的动机,在某些情况下,可能会导致您甚至不知道您的程序出现故障 相反,最好的处理方法是让程序崩溃,记录崩溃(以及堆栈/核心转储),然后使用pm2或nodemon自动重新启动它 对于Joyent(节点

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

您可以使用域API: 但它已被弃用,无论如何也不推荐使用

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

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

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

对于Joyent(节点创建者)的(非常)长但有深刻见解的演讲,我强烈建议您阅读以下链接:

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

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

为此,您可能想看看像keymetrics这样的接口(制造pm2的是同一个人),它可能会在错误时提醒您

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

  • 当你的应用程序(重新)启动时,它会查找错误日志
  • 如果它找到一个,它会用日志文件的内容提醒您
  • 然后将错误日志文件重命名/移动到其他位置
我没有必要推荐这个解决方案,但它符合您需要的所有规格,所以请享受它的乐趣

编辑2:如果您想深入探讨服务开发和最佳实践的主题,请查看@Paul在评论中建议的链接:

您可以使用“
uncaughtException
”和“
unhandledrefraction
”事件

还请记住,在“
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);
  });

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

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)
})
var cluster=require('cluster');
var numpus=require('os').cpus().length;
if(cluster.isMaster){
对于(变量i=0;i{
log(`worker${worker.process.pid}`);
cluster.fork();
});
}否则{
var http=require('http');
var httpServer=http.createServer(app).listen(httpPort,函数(){
console.log('process id local',process.pid)
log(“http服务器启动于端口”+httpPort);
});
}
process.on('uncaughtException',函数(err){
console.error((新日期).toutString()+'uncaughtException:',err.message)
控制台错误(错误堆栈)
进程。退出(1)
})

`

你的意思是,当节点服务器崩溃时,你想要一封电子邮件?是的。发送邮件附加一条错误消息,以便我知道发生了什么。Joyent文章的链接为+1。另外,请特别注意标题为(非)处理程序员错误的部分,我认为这是OP问题的核心。还值得注意的是,node遵循unix原则,这意味着每个应用程序都应该做好一件事。如果应用程序崩溃时需要电子邮件,这超出了应用程序的范围。相反,正如@xShirase所说,您崩溃(并记录),然后让其他人(如systemd或logwatch)记下这一点,并在达到阈值时发送电子邮件(即使该阈值是“任何错误”).刚刚添加了一个我年轻时使用的技巧,在应用程序本身中不小心这样做:)+1对于unix原则,我认为节点开发人员似乎都经历了一系列“启蒙阶段”(至少,我所知道/观察到的所有阶段,包括我自己),您从enterprisey最佳实践背景开始,尝试以某种方式打包所有内容,直到后来才学会放手并信任环境和支持工具。12factor.net是一个很好的资源,可以帮助您实现这一点,但很多人都在学习可用的工具。我最近才开始使用systemd和logstash等工具来完成我以前对pm2和自定义代码所做的工作。无新车轮。:)掌握Unix就是掌握大量的工具。我也经历过同样的阶段,但我意识到我知道如何使用经过测试的unix工具完成所有这些任务,这些工具运行得更快,而且通常比修补节点解决方案更好。我喜欢看我的旧代码,里面充满了不必要的东西:)可以,但不应该。请看@xShirase的答案。你是对的,保罗。为此,在示例中,我建议记录错误并停止de程序(退出代码为!==0),以避免应用程序处于未定义状态。是的,如果您要使用uncaughtException路由,我建议您使用正确的技术,我只是想进一步说明这不是最佳路由,不要让OP认为他应该做你所做的,然后在事件侦听器中嵌入某种电子邮件发送者。非常感谢。