几天前我刚开始试用node.js。我已经意识到,每当我的程序中出现未处理的异常时,节点就会终止。这与我所接触的正常服务器容器不同,在正常服务器容器中,当发生未处理的异常时,只有工作线程死亡,并且容器仍然能够接收请求。这引发了几个问题:

process.on('ncaughtException')是防范它的唯一有效方法吗?process.on('ncaughtException')是否也会在异步进程执行期间捕获未处理的异常?是否有一个已经构建好的模块(例如发送电子邮件或写入文件),我可以在未捕获的异常情况下利用它?

如果有任何指针/文章向我展示在node.js中处理未捕获异常的常见最佳实践,我将不胜感激


当前回答

前段时间读了这篇文章后,我想知道在api/函数级别上使用域进行异常处理是否安全。我想用它们来简化我编写的每个异步函数中的异常处理代码。我担心的是,为每个函数使用一个新域会引入大量开销。我的作业似乎表明开销最小,而且在某些情况下,域的性能实际上比try-catch要好。

http://www.lighthouselogic.com/#/using-a-new-domain-for-each-async-function-in-node/

其他回答

使用try-catch可能比较合适的一个例子是使用forEach循环。它是同步的,但同时不能只在内部范围中使用return语句。相反,可以使用try-and-catch方法在适当的范围内返回Error对象。考虑:

function processArray() {
    try { 
       [1, 2, 3].forEach(function() { throw new Error('exception'); }); 
    } catch (e) { 
       return e; 
    }
}

这是上面@balupton描述的方法的组合。

您可以捕获未捕获的异常,但它的用处有限。看见http://debuggable.com/posts/node-js-dealing-with-uncaught-exceptions:4c933d54-1428-434c-928d-4e1ecbd56cb

monit、forever或upstart可用于在节点进程崩溃时重新启动它。您最希望的是一个优雅的关闭(例如,将所有内存中的数据保存在未捕获的异常处理程序中)。

我最近在http://snmaynard.com/2012/12/21/node-error-handling/.0.8版本中node的一个新功能是域,它允许您将所有形式的错误处理合并到一个更简单的管理表单中。您可以在我的文章中阅读它们。

您还可以使用Bugsnag之类的工具来跟踪未捕获的异常,并通过电子邮件、聊天室或创建未捕获异常的罚单(我是Bugsnag的联合创始人)获得通知。

这里已经很好地讨论了捕获错误,但值得记住的是将错误记录在某个位置,以便您可以查看它们并修复它们。

​Bunyan是NodeJS的一个流行日志框架,它支持向一系列不同的输出位置进行输出,这使得它对本地调试非常有用,只要您避免console.log。​在域的错误处理程序中,可以将错误输出到日志文件中。

var log = bunyan.createLogger({
  name: 'myapp',
  streams: [
    {
      level: 'error',
      path: '/var/tmp/myapp-error.log'  // log ERROR to this file
    }
  ]
});

如果您有大量错误和/或服务器需要检查,这可能会很耗时,因此值得研究Raygun(免责声明,我在Raygun工作)这样的工具来将错误分组在一起,或者将两者同时使用。​如果您决定使用Raygun作为工具,那么设置也非常简单

var raygunClient = new raygun.Client().init({ apiKey: 'your API key' });
raygunClient.send(theError);

​在使用PM2或永久性工具的情况下,你的应用程序应该能够崩溃、注销发生的事情并重新启动,而不会出现任何重大问题。

前段时间读了这篇文章后,我想知道在api/函数级别上使用域进行异常处理是否安全。我想用它们来简化我编写的每个异步函数中的异常处理代码。我担心的是,为每个函数使用一个新域会引入大量开销。我的作业似乎表明开销最小,而且在某些情况下,域的性能实际上比try-catch要好。

http://www.lighthouselogic.com/#/using-a-new-domain-for-each-async-function-in-node/