【问题标题】:NodeJS domain error handling not picking up ReferenceErrorNodeJS 域错误处理未获取 ReferenceError
【发布时间】:2015-11-05 17:34:55
【问题描述】:

我在 NodeJS 中遇到了域问题。我已经设置了一些中间件功能,域包装了我在 Web 应用程序中进行的每个调用。我的目标是能够发现发生的任何错误,对其进行处理,并返回有关所发生错误的有用信息。

这适用于大多数错误,但我看到域要么没有看到,要么在 ReferenceError 上触发了我的事件处理程序。我已经尝试了很多东西,并环顾了很多地方,但无济于事。我认为错误和异常之间可能存在差异,但这尚未得到证实。

我注意到,由于我正在侦听 Error 事件,因此可能不会在某些类型的错误(如 ReferenceError)上触发此类事件。

我尝试将我的代码包装在 process.nextTick 中,并将错误代码放入 async.js 块中。

我尝试使用https://github.com/brianc/node-domain-middleware 作为修复。

我尝试监听域的错误事件,监听 EventEmitter 并将该发射器添加到域中。

以及使用域对象本身的进入和退出方法。我敢肯定还有更多我现在记不起来的事情。

真的,我正在寻找的只是一种解决方案,它可以捕获我的 nodejs Web 应用程序中发生的任何错误,并允许我处理发生的错误。

有一个每次都执行的总体中间件,并且中间件仅在 api 调用上起作用。 api 调用的中间件会检查您是否已通过身份验证(在应用程序的另一部分中有效并经过验证)。

是的,我已经尝试为这两个中间件中的每个请求创建一个域,并且我尝试按照我能想到的这两个中间件之间的每个顺序和组合创建和放置这些 error_handling_domain.run 语句。每次都一样,没有输出或信号表明错误处理程序已被触发。

代码:

    var error_handling_domain = domain.create();
    var EventEmitter = require('events').EventEmitter;
    var emitter = new EventEmitter();

    error_handling_domain.on('error', function(er) {
      console.log("i caught an error");
      console.log(er);
    });

    emitter.on('error', function(err) {
      console.log("I am an emitter error");
      console.log(err);
    });

    error_handling_domain.add(emitter);

    app.use(function(req, res, next) {
      error_handling_domain.run(function() {
        next();
      });
    });

    app.all('/api/*', function(req, res, next) {
      var original_url_prefix = req.originalUrl.split('/')[1];
      original_url_prefix = (original_url_prefix) ? original_url_prefix.toLowerCase() : "";
      req.user = "me";
      var authentication_required = original_url_prefix === 'api' && !req.user;
      if (authentication_required) {
        res.sendStatus(401);
      } else {
        next();
      }
    });

app.post('/api/my_route/here', handle_post);

function handle_post(req, resp){
  switch(req.body.action){
    case 'download': this.download_report(req.body, resp);
  }
}

function download_report(params, resp){    
  wellhi.thing;    
  resp.json({success: "I guess"});
}

假设我在 '/api/my_route/here' 上发帖,会调用 download_report 并尝试引用 wellhi.thing,这显然不是真实的东西。这是我正在使用的测试错误代码。

我正在使用 NodeJS 和 expressjs。我一直在努力熟悉以下页面:

https://nodejs.org/api/errors.html#errors_class_referenceerror

http://tuttlem.github.io/2015/05/16/handling-exceptions-with-domains-in-nodejs.html

https://strongloop.com/strongblog/robust-node-applications-error-handling/

https://nodejs.org/api/domain.html http://www.lighthouselogic.com/node-domains-as-a-replacement-for-try-catch/

我看过的 Stackoverflow 帖子:

Domains not properly catching errors while testing nodeJS in mocha

NodeJS Domains and expressjs

如果我可以添加更多信息来帮助澄清,请告诉我。

【问题讨论】:

    标签: javascript node.js asynchronous express error-handling


    【解决方案1】:

    很遗憾,我已经接受似乎没有办法使用域完全处理每个错误。

    我所做的远非我想要的——我在其他路由之后专门设置了一个 expressjs 错误处理路由。我已经将错误处理隔离到它自己的函数中,并且 Domain 和 expressjs 路由都指向该错误处理函数。

    无论出于何种原因,这似乎捕获了 Domains 拒绝捕获的意外错误(如 ReferenceError)。因此,我同时使用两个错误捕获。我有点担心这种方法可能存在重叠和潜在冲突。

    纯属猜测:似乎某些错误不会发出错误事件,这可能是域未触发的原因。

    当时的策略是:

    • 域:我可以预测的错误 // 特别是抛出 // 注意
    • Expressjs:我无法预测的意外错误

    代码:

    function error_handling(err, req, res) {
      console.log("hello im an error.");   
    }
    
    var error_handling_domain = domain.create();
    error_handling_domain.on("error", error_handling);
    
    app.use(function(req, res, next) {  
      error_handling_domain.run(function(){                
        next();
      });    
    });
    
    app.use('/api', function(req, res, next){      
      var authentication_required = <check_for_auth>;
      if(authentication_required) {
        res.sendStatus(401);                
      } else {        
        next();                   
      }  
    });
    
    var routes = require('routes.js');
    routes.initialize(app);
    
    app.use(function(err, req, res, next) {
      error_handling(err, req, res)
    });

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 2018-07-03
      • 1970-01-01
      • 2017-10-13
      • 2017-04-19
      • 2018-12-10
      • 2019-10-20
      • 2022-12-31
      • 2023-04-01
      相关资源
      最近更新 更多