Skip to content

Commit 68e444d

Browse files
cola119RafaelGSS
authored andcommitted
http: add diagnostics channel http.client.request.error
PR-URL: #54054 Reviewed-By: Paolo Insogna <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Marco Ippolito <[email protected]> Reviewed-By: Ethan Arrowood <[email protected]>
1 parent 5e03c17 commit 68e444d

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

‎doc/api/diagnostics_channel.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,13 @@ independently.
11291129

11301130
Emitted when client starts a request.
11311131

1132+
`http.client.request.error`
1133+
1134+
*`request`{http.ClientRequest}
1135+
*`error`{Error}
1136+
1137+
Emitted when an error occurs during a client request.
1138+
11321139
`http.client.response.finish`
11331140

11341141
*`request`{http.ClientRequest}

‎lib/_http_client.js‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,19 @@ const kClientRequestStatistics = Symbol('ClientRequestStatistics');
9090

9191
constdc=require('diagnostics_channel');
9292
constonClientRequestStartChannel=dc.channel('http.client.request.start');
93+
constonClientRequestErrorChannel=dc.channel('http.client.request.error');
9394
constonClientResponseFinishChannel=dc.channel('http.client.response.finish');
9495

96+
functionemitErrorEvent(request,error){
97+
if(onClientRequestErrorChannel.hasSubscribers){
98+
onClientRequestErrorChannel.publish({
99+
request,
100+
error,
101+
});
102+
}
103+
request.emit('error',error);
104+
}
105+
95106
const{ addAbortSignal, finished }=require('stream');
96107

97108
letdebug=require('internal/util/debuglog').debuglog('http',(fn)=>{
@@ -343,7 +354,7 @@ function ClientRequest(input, options, cb){
343354
if(typeofopts.createConnection==='function'){
344355
constoncreate=once((err,socket)=>{
345356
if(err){
346-
process.nextTick(()=>this.emit('error',err));
357+
process.nextTick(()=>emitErrorEvent(this,err));
347358
}else{
348359
this.onSocket(socket);
349360
}
@@ -465,7 +476,7 @@ function socketCloseListener(){
465476
// receive a response. The error needs to
466477
// fire on the request.
467478
req.socket._hadError=true;
468-
req.emit('error',newConnResetException('socket hang up'));
479+
emitErrorEvent(req,newConnResetException('socket hang up'));
469480
}
470481
req._closed=true;
471482
req.emit('close');
@@ -492,7 +503,7 @@ function socketErrorListener(err){
492503
// For Safety. Some additional errors might fire later on
493504
// and we need to make sure we don't double-fire the error event.
494505
req.socket._hadError=true;
495-
req.emit('error',err);
506+
emitErrorEvent(req,err);
496507
}
497508

498509
constparser=socket.parser;
@@ -516,7 +527,7 @@ function socketOnEnd(){
516527
// If we don't have a response then we know that the socket
517528
// ended prematurely and we need to emit an error on the request.
518529
req.socket._hadError=true;
519-
req.emit('error',newConnResetException('socket hang up'));
530+
emitErrorEvent(req,newConnResetException('socket hang up'));
520531
}
521532
if(parser){
522533
parser.finish();
@@ -541,7 +552,7 @@ function socketOnData(d){
541552
socket.removeListener('end',socketOnEnd);
542553
socket.destroy();
543554
req.socket._hadError=true;
544-
req.emit('error',ret);
555+
emitErrorEvent(req,ret);
545556
}elseif(parser.incoming&&parser.incoming.upgrade){
546557
// Upgrade (if status code 101) or CONNECT
547558
constbytesParsed=ret;
@@ -872,7 +883,7 @@ function onSocketNT(req, socket, err){
872883
err=newConnResetException('socket hang up');
873884
}
874885
if(err){
875-
req.emit('error',err);
886+
emitErrorEvent(req,err);
876887
}
877888
req._closed=true;
878889
req.emit('close');

‎test/parallel/test-diagnostics-channel-http.js‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22
constcommon=require('../common');
3+
const{ addresses }=require('../common/internet');
34
constassert=require('assert');
45
consthttp=require('http');
56
constnet=require('net');
@@ -9,9 +10,15 @@ const isHTTPServer = (server) => server instanceof http.Server;
910
constisIncomingMessage=(object)=>objectinstanceofhttp.IncomingMessage;
1011
constisOutgoingMessage=(object)=>objectinstanceofhttp.OutgoingMessage;
1112
constisNetSocket=(socket)=>socketinstanceofnet.Socket;
13+
constisError=(error)=>errorinstanceofError;
1214

1315
dc.subscribe('http.client.request.start',common.mustCall(({ request })=>{
1416
assert.strictEqual(isOutgoingMessage(request),true);
17+
},2));
18+
19+
dc.subscribe('http.client.request.error',common.mustCall(({ request, error })=>{
20+
assert.strictEqual(isOutgoingMessage(request),true);
21+
assert.strictEqual(isError(error),true);
1522
}));
1623

1724
dc.subscribe('http.client.response.finish',common.mustCall(({
@@ -50,8 +57,14 @@ const server = http.createServer(common.mustCall((req, res) =>{
5057
res.end('done');
5158
}));
5259

53-
server.listen(()=>{
60+
server.listen(async()=>{
5461
const{ port }=server.address();
62+
constinvalidRequest=http.get({
63+
host: addresses.INVALID_HOST,
64+
});
65+
awaitnewPromise((resolve)=>{
66+
invalidRequest.on('error',resolve);
67+
});
5568
http.get(`http://localhost:${port}`,(res)=>{
5669
res.resume();
5770
res.on('end',()=>{

0 commit comments

Comments
(0)