20

好的,所以我有一个问题。如果在处理 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);

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

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

4

3 回答 3

16

当发生未捕获的异常时,您处于不干净的状态。让进程终止并重新启动它,您无法安全地将其恢复到已知良好状态。使用forever,它会在它死后立即重新启动您的进程。

于 2011-11-13T21:43:45.340 回答
1

如果同步抛出错误,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 错误响应。

于 2019-01-22T15:13:42.987 回答
-1

使用 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);
});
于 2011-11-14T03:07:52.180 回答