@@ -221,6 +221,7 @@ export class SSEStreamSubscription implements StreamSubscription {
221221 private retryCount = 0 ;
222222 private stallCount = 0 ;
223223 private maxRetries : number ;
224+ private maxStallRetries : number ;
224225 private retryDelayMs : number ;
225226 private maxRetryDelayMs : number ;
226227 private retryJitter : number ;
@@ -296,6 +297,7 @@ export class SSEStreamSubscription implements StreamSubscription {
296297 this . lastEventId = options . lastEventId ;
297298 this . from = options . from ?? "beginning" ;
298299 this . maxRetries = options . maxRetries ?? Infinity ;
300+ this . maxStallRetries = options . maxStallRetries ?? Infinity ;
299301 this . retryDelayMs = options . retryDelayMs ?? 100 ;
300302 this . maxRetryDelayMs = options . maxRetryDelayMs ?? 5000 ;
301303 this . retryJitter = options . retryJitter ?? 0.5 ;
@@ -653,13 +655,12 @@ export class SSEStreamSubscription implements StreamSubscription {
653655 return ;
654656 }
655657
656- if (
657- this . retryCount >= this . maxRetries ||
658- this . stallCount > ( this . options . maxStallRetries ?? Infinity )
659- ) {
658+ const stallsExhausted = this . stallCount > this . maxStallRetries ;
659+ if ( this . retryCount >= this . maxRetries || stallsExhausted ) {
660660 // Internal timeouts are failures, not caller cancellation.
661- const finalError =
662- error ?. name === "AbortError"
661+ const finalError = stallsExhausted
662+ ? new Error ( "Stream stalled: no records received" )
663+ : error ?. name === "AbortError"
663664 ? new Error ( "Stream connection retries exhausted" )
664665 : error || new Error ( "Max retries reached" ) ;
665666 controller . error ( finalError ) ;
0 commit comments