The following code runs a domain and creates a http request. The request tries to connect to an unknown host, which emits the error event of the request. The request error handler passes the error to the domain error handler by throwing it.
In my understanding the request error event should be emitted one time with ECONNREFUSED, but instead it's emitted two times: first with ECONNREFUSED and then with ECONNRESET.
However, when I don't use a domain the code works as expected (only one error). Same when I use a domain, but don't throw the error. It also works when I use a normal EventEmitter object instead of a http request.
Can anyone explain this behaviour to me and tell me how to get the error handling fixed inside the domain?
// 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);
}
Two things are causing the problems mentioned in the question:
onError handler if the object is already managed by a domain.1. This is a simple coding error. A Node.js domain implicitly handles all error-events of objects that are created within the domain. Adding yet another error-event handler that calls onDomError causes onDomError to be called twice. One time directly from the domain and another time from the additional event handler.
2. This might be a bug in Node.js. Creating a Request via http.createRequest() adds one or two additional references of the active domain to the domain stack. This causes onDomError to be called multiple times. First by the topmost domain on the stack, the thrown error will then passed to the next domain on the stack, which calls onDomError again, and so on... Well, it's difficult to explain ;) See Node issue #8429 and Node issue #8429 on GitHub for more details.