无法使用express处理node.js域的异常

use*_*983 15 dns exception node.js express node.js-domains

我想使用Node.js域来捕获异常.它到目前为止工作,但有一个地方我无法获得域来捕获异常.回调中的exception2在domain.on('error')处理程序中被捕获和处理,但是没有捕获exception1.奇怪的是,当抛出exception1时,它不像我期望的那样关闭Node.这是我的示例应用程序:

var domain = require('domain');
var request = require('request');
var express = require('express');

var serverDomain = domain.create();
serverDomain.on('error', function(err) {
  console.log("Server Domain Error: " + err);
});

var app;

serverDomain.run(function() {
  app = express();
  app.listen(3000);
});

app.use(function(req, res, next) {

  var reqDomain = domain.create();
  reqDomain.add(req);
  reqDomain.add(res);
  reqDomain.on('error', function(err) {
    console.log("Req Domain Error: " + err);
    reqDomain.dispose();
    next(err);
  });

  next();
});

app.get('/', function(req, res) {
  var uri = "http://google.com";

  exception1.go();

  request.get({url:uri, json: {}},
    function (error, response, body) {
      if(response.statusCode === 200) {
        exception2.go();
        res.send('Success getting google response');
      }
    });
});
Run Code Online (Sandbox Code Playgroud)

为了让exception2执行,我注释掉异常1.

Tim*_*del 18

问题是在Connect的路由过程中发生了异常,它在执行过程中都有一个try/catch块,还有一个默认的错误处理程序,它在非生产模式下运行时打印出堆栈跟踪详细信息.由于异常是在Express内部处理的,因此它永远不会到达外层以供域处理.

它的不同之处在于路由exception2的处理函数'/'由Connect块直接执行,与通过Express的原始调用在同一堆栈中.第二个异常发生在回调中,在一些I/O操作返回后,因此由来自Node的事件循环I/O处理程序的堆栈执行,因此try/catchExpress无法阻止该异常并保存应用服务器.事实上,如果你注释掉所有的域名,exception2那么它就会崩溃节点.

由于只有未处理的异常被路由到域机制,并且因为它上面的调用堆栈中exception1有一个try/catch可见的异常,所以处理异常,而不是转发到域.