@@ -140,6 +140,8 @@ export class Http2SubchannelCall implements SubchannelCall {
140
140
141
141
private serverEndedCall = false ;
142
142
143
+ private connectionDropped = false ;
144
+
143
145
constructor (
144
146
private readonly http2Stream : http2 . ClientHttp2Stream ,
145
147
private readonly callEventTracker : CallEventTracker ,
@@ -240,8 +242,16 @@ export class Http2SubchannelCall implements SubchannelCall {
240
242
details = 'Stream refused by server' ;
241
243
break ;
242
244
case http2 . constants . NGHTTP2_CANCEL :
243
- code = Status . CANCELLED ;
244
- details = 'Call cancelled' ;
245
+ /* Bug reports indicate that Node synthesizes a NGHTTP2_CANCEL
246
+ * code from connection drops. We want to prioritize reporting
247
+ * an unavailable status when that happens. */
248
+ if ( this . connectionDropped ) {
249
+ code = Status . UNAVAILABLE ;
250
+ details = 'Connection dropped' ;
251
+ } else {
252
+ code = Status . CANCELLED ;
253
+ details = 'Call cancelled' ;
254
+ }
245
255
break ;
246
256
case http2 . constants . NGHTTP2_ENHANCE_YOUR_CALM :
247
257
code = Status . RESOURCE_EXHAUSTED ;
@@ -321,10 +331,15 @@ export class Http2SubchannelCall implements SubchannelCall {
321
331
}
322
332
323
333
public onDisconnect ( ) {
324
- this . endCall ( {
325
- code : Status . UNAVAILABLE ,
326
- details : 'Connection dropped' ,
327
- metadata : new Metadata ( ) ,
334
+ this . connectionDropped = true ;
335
+ /* Give the call an event loop cycle to finish naturally before reporting
336
+ * the disconnection as an error. */
337
+ setImmediate ( ( ) => {
338
+ this . endCall ( {
339
+ code : Status . UNAVAILABLE ,
340
+ details : 'Connection dropped' ,
341
+ metadata : new Metadata ( ) ,
342
+ } ) ;
328
343
} ) ;
329
344
}
330
345
0 commit comments