【问题标题】:Express js error handlingExpress js 错误处理
【发布时间】:2013-03-28 14:13:55
【问题描述】:

我正在尝试使用 express 运行错误处理,但没有看到“错误!!!”的响应就像我希望我在控制台上看到“一些异常”,然后进程被杀死。这是应该如何设置错误处理,如果是这样,是否有其他方法来捕获错误?

var express = require('express');
var app = express();

app.use(function(err, req, res, next) {
    console.log("error!!!");
    res.send("error!!!");
});

app.get('/', function(request, response) {
    throw "some exception";
    response.send('Hello World!');
});

app.listen(5000, function() {
  console.log("Listening on 5000");
});

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    有关错误处理的示例应用程序/指南可在 https://expressjs.com/en/guide/error-handling.html 但是应该修复您的代码:

    // Require Dependencies
    var express = require('express');
    var app = express();
    
    // Middleware
    app.use(app.router); // you need this line so the .get etc. routes are run and if an error within, then the error is parsed to the next middleware (your error reporter)
    app.use(function(err, req, res, next) {
        if(!err) return next(); // you also need this line
        console.log("error!!!");
        res.send("error!!!");
    });
    
    // Routes
    app.get('/', function(request, response) {
        throw "some exception";
        response.send('Hello World!');
    });
    
    // Listen
    app.listen(5000, function() {
      console.log("Listening on 5000");
    });
    

    【讨论】:

    【解决方案2】:

    一些提示:

    1) 您的代码无法正常工作,因为您的错误处理程序中间件是在到达您的路由之前运行的,因此错误处理程序永远没有机会将错误传递给它。这种风格被称为延续传递。将错误处理程序放在中间件堆栈的最后。

    2) 当您遇到未处理的错误时,您应该关闭服务器。最好的方法是调用server.close(),其中服务器是var server = http.createServer(app);的结果

    也就是说,你应该这样做:

    var server = http.createServer(app);
    
    app.use(function(err, req, res, next) {
      console.log("error!!!");
      res.send("error!!!");
      server.close();
    });
    

    您可能还应该让 server.close() 超时,以防它无法完成(毕竟您的应用处于未定义状态):

    var server = http.createServer(app);
    
    app.use(function(err, req, res, next) {
      console.log("error!!!");
      res.send("error!!!");
    
      server.close();
    
      setTimeout(function () {
        process.exit(1);
      }, 3*1000);
    });
    

    我创建了一个库,可以为您完成所有这些工作,并允许您定义自定义响应,包括专门的错误视图、要提供的静态文件等...:

    https://github.com/ericelliott/express-error-handler

    【讨论】:

    • “你应该关闭服务器”?为什么?不!你不应该!
    • 如果您有一个未处理的错误,您绝对应该关闭服务器,因为该错误可能会使应用程序处于未定义状态——这意味着事情可能会出错。关机让应用有机会通过重新启动进入稳定状态来进行自我修复。
    • 所以如果有人触发了一个未处理的异常,那么整个应用程序都会停止运行?这是愚蠢的
    • 没有。 1.您应该始终有一个进程监控您的服务并在它们关闭时重新启动它们。 2.所有应用程序崩溃。为它计划。 3. 大多数 Node 应用程序可以在不到一秒的时间内重新启动,并且在规模上,服务器将进行负载平衡,因此其他实例可以填补空缺。 4. 如果你做你的工作,崩溃将是罕见的。 5. 在未处理的异常后运行代码是鲁莽的。您的代码可能正在造成损坏,每个人都无法自行修复。那是愚蠢的。 =)
    【解决方案3】:

    我遇到了同样的问题,但不知道出了什么问题。 问题是,如果您定义了 express errorHandler,那么您的自定义错误处理程序将永远不会被调用。 如果您有下一个代码,只需将其删除:

    if ('development' === app.get('env')) {
      app.use(express.errorHandler());
    }
    

    为我工作:)

    【讨论】:

      【解决方案4】:

      安装快速安装连接域,然后是这样的:

      var express = require("express"),  
          connectDomain = require("connect-domain"),
          app = express(),
          errorHandler;
      

      // 我们的错误处理程序

      app.use(connectDomain());  
          errorHandler = function (err, req, res, next) {  
              res.send(500, {
                 "status": "error",
                 "message": err.message
              });
          console.log(err);
      };
      

      然后在设置端点时,在 use() 中添加 errorHandler:

      app.get("/some/data", function (req, res) {  
          // ... do some stuff ...
          res.send(200, "Yay! Happy Success!");
      }).use(errorHandler);
      

      【讨论】:

        【解决方案5】:

        创建一个错误函数:

        function throwError(status, code, message) {
          const error = new Error(message);
          error.name = '';
          error.status = status;
          error.code = code;
          throw error;
        }
        

        例如

        throwError(422, 'InvalidEmail', '`email` should be a valid email address')
        

        我们将name 分配给'',这样当我们toString 错误时,它就不会在它前面加上"Error: "

        如前所述,如果您使用 express,您可以通过指定 4 个参数来创建特殊的错误处理中间件:

        app.use((err, req, res, next) => {
          if (err) {
            res.status(err.status || 500).json({ code: err.code || 'Error', message: err.toString() });
          }
        });
        

        如果您不使用 express 或其他方式,请将该代码添加到您的 catch 处理程序中。

        为什么?

        1. 现代应用程序处理 JSON,在 JSON 中抛出错误更有意义,并导致 UI 代码更简洁。

        2. 您不仅应该抛出错误消息,因为它们的解析不精确。如果 UI 是多语言应用程序怎么办?在这种情况下,他们可以使用code 来显示本地化消息。

        【讨论】:

          猜你喜欢
          • 2012-05-24
          • 2016-04-07
          • 1970-01-01
          • 2014-02-04
          • 1970-01-01
          • 2019-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多