@@ -140,6 +140,8 @@ export class Http2SubchannelCall implements SubchannelCall {
140140
141141 private serverEndedCall = false ;
142142
143+ private connectionDropped = false ;
144+
143145 constructor (
144146 private readonly http2Stream : http2 . ClientHttp2Stream ,
145147 private readonly callEventTracker : CallEventTracker ,
@@ -240,8 +242,16 @@ export class Http2SubchannelCall implements SubchannelCall {
240242 details = 'Stream refused by server' ;
241243 break ;
242244 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+ }
245255 break ;
246256 case http2 . constants . NGHTTP2_ENHANCE_YOUR_CALM :
247257 code = Status . RESOURCE_EXHAUSTED ;
@@ -321,10 +331,15 @@ export class Http2SubchannelCall implements SubchannelCall {
321331 }
322332
323333 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+ } ) ;
328343 } ) ;
329344 }
330345
0 commit comments