Node.js服务器崩溃,没有错误信息。

47

我有一个Node.js服务器,它经常在没有记录任何错误信息的情况下崩溃。这是一种典型情况吗?我该如何捕获错误并在崩溃前记录它?


1
除了记录未捕获的异常以查找崩溃原因外,您还可以检查进程是否耗尽内存。 - Phillip Kinkade
1
你能推荐一种检查服务器内存使用情况的方法吗? - Rick Eyre
我两年前的做法是从 shell 中运行我的节点服务器并捕获 stderr。那时的 V8 会不带任何警告退出并将错误消息写入 stderr。然而,V8 已经改变了很多,我不知道那种技术是否还有效。如果崩溃发生在长时间之后,监视进程内存可能会有所帮助。 - Phillip Kinkade
5个回答

65

在设置服务器监听器之前,尤其是在生产环境中,建议首先设置一个异常处理程序来记录详细信息。请参考这里

process.on('uncaughtException', function (exception) {
  console.log(exception); // to see your exception details in the console
  // if you are on production, maybe you can send the exception details to your
  // email as well ?
});
如果您正在使用Express.js,请查看此处了解如何查看完整的错误堆栈(如果您在生产环境中,可以将其发送到电子邮件中)。 在这种情况下,在实例化侦听器之前告诉它给您完整的细节。
var express = require('express');
// ...
var app = express();
var errorHandler = require('errorhandler')

// ...
app.use(errorHandler({ dumpExceptions: true, showStack: true })); 
// then, set the listener and do your stuff...

2019更新:您需要安装errorHandler包


9
errorHandler 中间件不再与 Express 捆绑在一起。您可以通过运行 npm install errorhandler 来安装它。有关详情,请参见此处 https://github.com/expressjs/errorhandler。 - muchweb
2
结果发现SQL默默地崩溃了进程,我不知道。所以多亏了这个,我能够追踪到它。谢谢。 - J-Cake

9
为了补充@matteofigus的回答,您还可以监听未处理的Promise拒绝事件
process.on('unhandledRejection', (reason, p) => {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});

somePromise.then((res) => {
  return reportToUser(JSON.pasre(res)); // note the typo (`pasre`)
}); // no `.catch` or `.then`

4
如果有人遇到类似的问题,我希望能帮到你:我的Node.js服务器崩溃了,但没有任何错误信息。在煎熬了一个小时之后,我意识到是代码中某处写入文件时使用了writeFileSync("./foo.json", "…"),这通常是可以的,但由于我正在使用PM2“监视”服务器目录以检测文件更改,也就是说,每当服务器目录中的文件更改时,PM2都会重新启动服务器,因此这导致了服务器“崩溃”。我通过为.data文件夹添加watch_ignore配置并将foo.json放在其中解决了这个问题。

3

Node v6.11.0,Windows 10。

尝试了这里的其他建议,但都无济于事 - 应用程序只是停止了,甚至没有错误信息

process.on('uncaughtException',...)
process.on('unhandledRejection',....)

最终追踪到一个递归函数调用导致退出/崩溃。以下代码展示了问题;
"use strict" ;

process.on('uncaughtException', function (exception) {
  console.log(exception); 
});

var count = 0 ;
function recursiveFunction(){
    console.log(count++);
    recursiveFunction();
}
recursiveFunction() ;

这段代码运行到一半就停了。即便使用了Try/Catch,也没能解决问题 - 尝试过上述方法,但仍旧不行;
function recursiveFunction(){
    console.log(count++);
    try{
        recursiveFunction();
    }
    catch(e){
        console.log("recursion error");
    }
}

再次发生了停止情况,没有任何错误信息。

一个解决方法(无需重新设计代码)是使用setImmediate(避免递归过程);

function recursiveFunction(){
    console.log(count++);
    setImmediate(recursiveFunction);
}

最终我使用Ctrl+C停止了它。

Node.js的GitHub问题页面上报告了此问题。


1
您可以使用名为“errorhandler”的中间件,并且使用“logger”(log4js-npm-package)可以记录所有错误异常的日志。 这是Errorhandler的代码:
// 中间件:Catch-All错误处理程序。以便我们记录错误,但不向客户端泄漏内部错误详细信息。
app.use(errorHandler);

function errorHandler(err, req, res, next) {

// XHR Request?
if (req.xhr) {
    logger.error(err);
    res.status(500).send({ error: 'Internal Error Occured.' });
    return;
}

// Not a XHR Request.
logger.error(err);
res.status(500);
res.render('framework/error', { error: "Internal Server Error." });

// Note: No need to call next() as the buck stops here.
return;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接