Node.js域中的多个错误事件调用

时间:2014-09-16 10:23:29

标签: javascript node.js events error-handling

以下代码运行域并创建http请求。请求尝试连接到未知主机,该主机会发出请求的错误事件。请求错误处理程序通过抛出错误将错误传递给域错误处理程序。

根据我的理解,请求错误事件应该以ECONNREFUSED 一次发出,而是发出两次:首先使用ECONNREFUSED,然后使用ECONNRESET。

但是,当我不使用域时,代码按预期工作(只有一个错误)。我使用域时相同,但不抛出错误。当我使用普通的EventEmitter对象而不是http请求时,它也可以工作。

任何人都可以向我解释这种行为并告诉我如何在域内修复错误处理吗?

// The problem only occurs inside a domain
var dom = require("domain").create();
dom.addListener("error", onDomError);
dom.run(run);

// // If we don't use a domain everything works
// run();

function run() {
    console.log("run");

    // The following code should throw _one_ error, but throws two instead
    var req = require("http").request({
        'hostname': "localhost",
        'port': 1337,
        'method': "GET",
        'path': "/error"
    });
    req.addListener('error', onError);

    // // This code works as excpected
    // var EventEmitter = require('events').EventEmitter;
    // var emitter = new EventEmitter();
    // emitter.addListener("error", onError);
    // emitter.emit("error", "some error");

    // Throwing the error seems to cause the error
    function onError(error) {
        console.log("onError");
        throw error;
    }

    // If we don't throw the error everthing works
    // function onError(error) {
    //  console.log("onError");
    //  console.log(error)
    // }
}

function onDomError(error) {
    console.log("onDomError");
    console.log(error);
}

1 个答案:

答案 0 :(得分:0)

有两件事导致问题中提到的问题:

  1. 如果对象已由域管理,则无需添加onError处理程序。
  2. Node.js可能会将活动域的其他引用添加到域堆栈。
  3. 1。这是一个简单的编码错误。 Node.js域隐式处理域中创建的对象的所有错误事件。添加另一个调用onDomError的错误事件处理程序会导致onDomError被调用两次。一次直接来自域,另一次来自附加事件处理程序。

    2. 这可能是Node.js中的错误。通过http.createRequest()创建请求会将活动域的一个或两个其他引用添加到域名堆栈。这会导致多次调用onDomError。首先是堆栈中最顶层的域,然后抛出的错误将传递到堆栈上的下一个域,再次调用onDomError,依此类推......好吧,它很难解释;)有关详细信息,请参阅GitHub上的Node issue #8429Node issue #8429