From 51af17bd18c91586d74972883240b9eaf2a7cc96 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Tue, 18 Jul 2017 11:05:05 +0800 Subject: [PATCH] http: don't double-fire the req error event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit req.socket._hadError should be set before emitting the error event. PR-URL: https://github.com/nodejs/node/pull/14659 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Tobias Nießen --- lib/_http_client.js | 8 ++++---- ...est-http-client-req-error-dont-double-fire.js | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-http-client-req-error-dont-double-fire.js diff --git a/lib/_http_client.js b/lib/_http_client.js index dfcafbf11a6..e972a3d5b9e 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -373,8 +373,8 @@ function socketCloseListener() { // This socket error fired before we started to // receive a response. The error needs to // fire on the request. - req.emit('error', createHangUpError()); req.socket._hadError = true; + req.emit('error', createHangUpError()); } // Too bad. That output wasn't getting written. @@ -397,10 +397,10 @@ function socketErrorListener(err) { debug('SOCKET ERROR:', err.message, err.stack); if (req) { - req.emit('error', err); // For Safety. Some additional errors might fire later on // and we need to make sure we don't double-fire the error event. req.socket._hadError = true; + req.emit('error', err); } // Handle any pending data @@ -433,8 +433,8 @@ function socketOnEnd() { if (!req.res && !req.socket._hadError) { // If we don't have a response then we know that the socket // ended prematurely and we need to emit an error on the request. - req.emit('error', createHangUpError()); req.socket._hadError = true; + req.emit('error', createHangUpError()); } if (parser) { parser.finish(); @@ -455,8 +455,8 @@ function socketOnData(d) { debug('parse error', ret); freeParser(parser, req, socket); socket.destroy(); - req.emit('error', ret); req.socket._hadError = true; + req.emit('error', ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade or CONNECT var bytesParsed = ret; diff --git a/test/parallel/test-http-client-req-error-dont-double-fire.js b/test/parallel/test-http-client-req-error-dont-double-fire.js new file mode 100644 index 00000000000..3fca2aa843f --- /dev/null +++ b/test/parallel/test-http-client-req-error-dont-double-fire.js @@ -0,0 +1,16 @@ +'use strict'; +const assert = require('assert'); +const http = require('http'); +const common = require('../common'); + +// not exists host +const host = '*'.repeat(256); +const req = http.get({ host }); +const err = new Error('mock unexpected code error'); +req.on('error', common.mustCall(() => { + throw err; +})); + +process.on('uncaughtException', common.mustCall((e) => { + assert.strictEqual(e, err); +}));