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

Exception 从Node.JS中的未捕获异常恢复,exception,node.js,express,uncaught-exception,Exception,Node.js,Express,Uncaught Exception,好的,我有个问题。如果在处理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.ge

好的,我有个问题。如果在处理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);
如果您访问/出错,则会发生异常,但会被捕获。用户收到一条错误消息-没问题。但是,如果我访问/挂起,服务器最终将抛出一个未捕获的异常并永远挂起。任何后续请求/挂起都将挂起


这太糟糕了。有关于如何解决此问题的建议吗?

当发生未捕获的异常时,您处于不干净状态。让进程死掉并重新启动,您无法做任何其他事情来安全地将其恢复到已知的良好状态。使用,它将在进程死机后立即重新启动进程。

使用try/catch/finally

app.get('/hang', function(req, res, next) {
    console.log("In /hang route");
    setTimeout(function() {
        console.log("In /hang callback");
        try {
            if(reqNum >= 3)
                throw new Error("Problem occurred");
        } catch (err) {
            console.log("There was an error", err);
        } finally {
            res.send("It worked!");
        }
    }, 2000);
});

若同步抛出错误,express不会停止工作,只返回500

this.app.get("/error", (request, response) => {
  throw new Error("shouldn't stop");
});
若异步抛出错误,express将崩溃。但是根据它的说法,仍然有一种方法可以通过调用
next
从中恢复:

this.app.get("/error", (request, response, next) => {
  setTimeout(() => {
    try {
      throw new Error("shouldn't stop");
    } catch (err) {
      next(err);
    }
  }, 0);
});

这将使express尽其责任以500个错误进行响应。

我在一定程度上同意。在生产环境中,不能仅仅因为一个未捕获的异常就关闭整个服务器。如果一个PHP页面出现问题怎么办?您的整个web服务器会停机吗?如果发生未捕获的异常,我会让服务器给我发送电子邮件,如果在60秒内发生10次以上,服务器会自动关闭。但是,真的。。。我不希望服务器停机并重新启动。我想尝试恢复。@BMiner重新启动应用程序比为客户机的数据损坏道歉更容易。正如thejh所说,运行时处于不干净的状态。从现在起,你应该假设一切都是未定义的行为。@thejh为什么我必须假设我处于不洁状态?也许只有一部分程序被破坏了?为什么关闭并重新启动更安全?我相信你们,但我还是怀疑。你能举个例子吗?@BMiner:你说的是“也许”。问题是,
throw
就像一个GOTO,当事情完成一半时,它会跳出你的代码,现在你的状态可能会被破坏。示例:
user.name=newname;db.save(user.id,'name',newname)
-如果
db.save
在完成之前中断了怎么办?您的数据库包含的名称与RAM中的名称不同。完全同意@thejh,您应该让该进程立即停止(以避免数据中断等),然后重新启动服务器。但功能正常