一尘不染

无法使用Express处理Node.js域的异常

node.js

我想使用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');
      }
    });
});

为了使exception2执行,我注释掉了exception 1。


阅读 205

收藏
2020-07-07

共1个答案

一尘不染

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

它的区别在于,路由exception2的处理程序函数'/'直接由该Connect块执行,与通过Express进行的原始调用位于同一堆栈中。第二个异常发生在
回调中 ,返回了一些I / O操作之后,因此由Node的事件循环I /
O处理程序发起的堆栈执行,因此try/catchExpress的功能无法捕获该异常并保存应用服务器。实际上,如果您注释掉所有域内容,并exception2使其跳闸,则会使Node崩溃。

由于仅将未处理的异常路由到域机制,并且由于在其上方的调用堆栈中exception1try/catch可见的异常,因此将处理该异常,而不将其转发到域。

2020-07-07