@@ -190,6 +190,7 @@ function ClientRequest(input, options, cb) {
190190 }
191191
192192 this . _ended = false ;
193+ this . _errorEmitted = false ;
193194 this . res = null ;
194195 this . aborted = false ;
195196 this . timeoutCb = null ;
@@ -265,7 +266,7 @@ function ClientRequest(input, options, cb) {
265266 return ;
266267 called = true ;
267268 if ( err ) {
268- process . nextTick ( ( ) => this . emit ( 'error' , err ) ) ;
269+ process . nextTick ( emitError , this , err ) ;
269270 return ;
270271 }
271272 this . onSocket ( socket ) ;
@@ -324,6 +325,11 @@ ClientRequest.prototype.destroy = function destroy(error) {
324325 this . res . _dump ( ) ;
325326 }
326327
328+ if ( ! error ) {
329+ // No more errors after destroy has been called without error.
330+ this . _errorEmitted = true ;
331+ }
332+
327333 // In the event that we don't have a socket, we will pop out of
328334 // the request queue through handling in onSocket.
329335 if ( this . socket ) {
@@ -337,6 +343,13 @@ ClientRequest.prototype.abort = function abort() {
337343 this . destroy ( ) ;
338344} ;
339345
346+ function emitError ( req , err ) {
347+ if ( ! req . _errorEmitted ) {
348+ req . _errorEmitted = true ;
349+ req . emit ( 'error' , err ) ;
350+ }
351+ }
352+
340353function emitAbortNT ( ) {
341354 this . emit ( 'abort' ) ;
342355}
@@ -371,15 +384,10 @@ function socketCloseListener() {
371384 res . emit ( 'close' ) ;
372385 }
373386 } else {
374- if ( ! req . socket . _hadError ) {
375- // This socket error fired before we started to
376- // receive a response. The error needs to
377- // fire on the request.
378- req . socket . _hadError = true ;
379- if ( ! req . aborted ) {
380- req . emit ( 'error' , connResetException ( 'socket hang up' ) ) ;
381- }
382- }
387+ // This socket error fired before we started to
388+ // receive a response. The error needs to
389+ // fire on the request.
390+ emitError ( req , connResetException ( 'socket hang up' ) ) ;
383391 req . emit ( 'close' ) ;
384392 }
385393
@@ -401,12 +409,7 @@ function socketErrorListener(err) {
401409 debug ( 'SOCKET ERROR:' , err . message , err . stack ) ;
402410
403411 if ( req ) {
404- // For Safety. Some additional errors might fire later on
405- // and we need to make sure we don't double-fire the error event.
406- req . socket . _hadError = true ;
407- if ( ! req . aborted ) {
408- req . emit ( 'error' , err ) ;
409- }
412+ emitError ( req , err ) ;
410413 }
411414
412415 // Handle any pending data
@@ -436,13 +439,10 @@ function socketOnEnd() {
436439 const req = this . _httpMessage ;
437440 const parser = this . parser ;
438441
439- if ( ! req . res && ! req . socket . _hadError ) {
442+ if ( ! req . res ) {
440443 // If we don't have a response then we know that the socket
441444 // ended prematurely and we need to emit an error on the request.
442- req . socket . _hadError = true ;
443- if ( ! req . aborted ) {
444- req . emit ( 'error' , connResetException ( 'socket hang up' ) ) ;
445- }
445+ emitError ( req , connResetException ( 'socket hang up' ) ) ;
446446 }
447447 if ( parser ) {
448448 parser . finish ( ) ;
@@ -464,10 +464,7 @@ function socketOnData(d) {
464464 debug ( 'parse error' , ret ) ;
465465 freeParser ( parser , req , socket ) ;
466466 socket . destroy ( ) ;
467- req . socket . _hadError = true ;
468- if ( ! req . aborted ) {
469- req . emit ( 'error' , ret ) ;
470- }
467+ emitError ( req , ret ) ;
471468 } else if ( parser . incoming && parser . incoming . upgrade ) {
472469 // Upgrade (if status code 101) or CONNECT
473470 var bytesParsed = ret ;
@@ -725,10 +722,12 @@ function onSocketNT(req, socket) {
725722 socket . destroy ( req . _destroyError ) ;
726723 } else {
727724 if ( req . _destroyError ) {
728- req . emit ( 'error' , req . _destroyError ) ;
725+ emitError ( req , req . _destroyError ) ;
729726 }
727+ req . emit ( 'close' ) ;
730728 socket . emit ( 'free' ) ;
731729 }
730+ req . _destroyError = null ;
732731 } else {
733732 tickOnSocket ( req , socket ) ;
734733 }
0 commit comments