xem xét sau mã javascript thực hiện trong nodejs:NodeJS: http.ClientRequest bắn kiện lỗi hai lần trong kịch bản cụ thể
// create ClientRequest
// port 55555 is not opened
var req = require('http').request('http://localhost:55555', function() {
console.log('should be never reached');
});
function cb() {
throw new Error();
}
req.on('error', function(e) {
console.log(e);
cb();
});
// exceptions handler
process.on('uncaughtException', function() {
console.log('exception caught. doing some async clean-up before exit...');
setTimeout(function() {
console.log('exiting');
process.exit(1);
}, 2000);
});
// send request
req.end();
Dự kiến sản lượng:
{ Error: connect ECONNREFUSED 127.0.0.1:55555
at Object.exports._errnoException (util.js:1026:11)
at exports._exceptionWithHostPort (util.js:1049:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1081:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 55555 }
exception caught. doing some async clean-up before exit...
exiting
đầu ra thực tế:
{ Error: connect ECONNREFUSED 127.0.0.1:55555
at Object.exports._errnoException (util.js:1026:11)
at exports._exceptionWithHostPort (util.js:1049:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1081:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 55555 }
exception caught. doing some async clean-up before exit...
{ Error: socket hang up
at createHangUpError (_http_client.js:252:15)
at Socket.socketCloseListener (_http_client.js:284:23)
at emitOne (events.js:101:20)
at Socket.emit (events.js:188:7)
at TCP._handle.close [as _onclose] (net.js:492:12) code: 'ECONNRESET' }
exception caught. doing some async clean-up before exit...
exiting
Như bạn có thể thấy, http.ClientRequest (hoặc có thể stream.Writable?) Kích hoạt sự kiện lỗi hai lần, trước tiên với ECONNREFUSED và phía sau er ngoại lệ bị bắt, ECONNRESET.
Điều này không xảy ra nếu chúng tôi thực thi gọi lại không đồng bộ trong trình xử lý lỗi http.ClientRequest bằng cách sử dụng nextTick hoặc setTimeout, ví dụ: thay đổi này mang lại hành vi mong đợi:
req.on('error', function(e) {
console.log(e);
process.nextTick(cb);
});
Bất cứ ai có thể giải thích tại sao điều này xảy ra và nếu đây là lỗi hoặc hoạt động như mong đợi? Hành vi giống nhau trong nút 4.x mới nhất và nút 6.x.
Cảm ơn!