从Node.JS中的未捕获异常中恢复

BMi*_*ner 19 exception node.js uncaught-exception express

好的,所以我有一个问题.如果在处理HTTP请求时发生未捕获的异常,我就没有机会在http.ServerResponse对象上调用end()方法.因此,服务器永远挂起,永远不会满足请求.

这是一个例子:

var express = require('express');
var app = express.createServer();
var reqNum = 0;
app.get('/favicon.ico', function(req, res) {res.send(404);});
app.get('*', function(req, res, next) {
    console.log("Request #", ++reqNum, ":", req.url);
    next();
});
app.get('/error', function(req, res, next) {
    throw new Error("Problem occurred");
});
app.get('/hang', function(req, res, next) {
    console.log("In /hang route");
    setTimeout(function() {
        console.log("In /hang callback");
        if(reqNum >= 3)
            throw new Error("Problem occurred");
        res.send("It worked!");
    }, 2000);
});
process.on('uncaughtException', function(err) {
    console.log("Uncaught exception!", err);
});
app.listen(8080);
Run Code Online (Sandbox Code Playgroud)

如果您访问/错误,则会发生异常,但会被捕获.用户收到错误消息 - 没问题.但是,如果我访问/挂起,服务器最终将抛出未捕获的异常并永久挂起.任何后续的/ hang请求都将挂起.

这很糟糕.有关如何解决此问题的任何建议?

the*_*ejh 15

当未捕获的异常发生时,您处于不洁净状态.让进程死掉并重新启动它,没有别的办法可以让它安全地恢复到已知状态.使用forever,它会在它死后立即重启.

  • 我同意在一定程度上.在生产环境中,由于一个未捕获的异常,您无法真正关闭整个服务器.如果单个PHP页面出现问题该怎么办?你的整个网络服务器会崩溃吗?如果发生未捕获的异常,我将让服务器给我发电子邮件,如果在60秒内发生超过10次,则自动关闭.但是,真的......我不希望服务器停机并重新启动.我想尝试恢复. (8认同)
  • @BMiner重新启动应用程序比为客户端数据损坏道歉更容易.正如他所说,运行时处于不洁净状态.从现在开始,您应该假设一切都是未定义的行为. (3认同)
  • @BMiner:你说"也许".问题是,`throw`就像一个GOTO,它会在你的代码完成时跳出你的代码,现在你的状态可能已经腐败了.示例:`user.name = newname; db.save(user.id,'name',newname)` - 如果`db.save`在它完成之前中断了怎么办?您的数据库包含的名称与RAM中的名称不同. (3认同)
  • 完全同意@thejh,您应该让进程立即终止(以避免数据损坏等),然后重新启动服务器。 (3认同)