@@ -27,7 +27,6 @@ export class ReconnectingWebSocket<TData = unknown>
2727{
2828 readonly #socketFactory: SocketFactory < TData > ;
2929 readonly #logger: Logger ;
30- readonly #apiRoute: string ;
3130 readonly #options: Required < ReconnectingWebSocketOptions > ;
3231 readonly #eventHandlers: {
3332 [ K in WebSocketEventType ] : Set < EventHandler < TData , K > > ;
@@ -39,6 +38,7 @@ export class ReconnectingWebSocket<TData = unknown>
3938 } ;
4039
4140 #currentSocket: UnidirectionalStream < TData > | null = null ;
41+ #lastRoute = "unknown" ; // Cached route for logging when socket is closed
4242 #backoffMs: number ;
4343 #reconnectTimeoutId: NodeJS . Timeout | null = null ;
4444 #isSuspended = false ; // Temporary pause, can be resumed via reconnect()
@@ -50,13 +50,11 @@ export class ReconnectingWebSocket<TData = unknown>
5050 private constructor (
5151 socketFactory : SocketFactory < TData > ,
5252 logger : Logger ,
53- apiRoute : string ,
5453 options : ReconnectingWebSocketOptions = { } ,
5554 onDispose ?: ( ) => void ,
5655 ) {
5756 this . #socketFactory = socketFactory ;
5857 this . #logger = logger ;
59- this . #apiRoute = apiRoute ;
6058 this . #options = {
6159 initialBackoffMs : options . initialBackoffMs ?? 250 ,
6260 maxBackoffMs : options . maxBackoffMs ?? 30000 ,
@@ -69,14 +67,12 @@ export class ReconnectingWebSocket<TData = unknown>
6967 static async create < TData > (
7068 socketFactory : SocketFactory < TData > ,
7169 logger : Logger ,
72- apiRoute : string ,
7370 options : ReconnectingWebSocketOptions = { } ,
7471 onDispose ?: ( ) => void ,
7572 ) : Promise < ReconnectingWebSocket < TData > > {
7673 const instance = new ReconnectingWebSocket < TData > (
7774 socketFactory ,
7875 logger ,
79- apiRoute ,
8076 options ,
8177 onDispose ,
8278 ) ;
@@ -88,6 +84,19 @@ export class ReconnectingWebSocket<TData = unknown>
8884 return this . #currentSocket?. url ?? "" ;
8985 }
9086
87+ /**
88+ * Extract the route (pathname + search) from the current socket URL for logging.
89+ * Falls back to the last known route when the socket is closed.
90+ */
91+ get #route( ) : string {
92+ const socketUrl = this . #currentSocket?. url ;
93+ if ( ! socketUrl ) {
94+ return this . #lastRoute;
95+ }
96+ const url = new URL ( socketUrl ) ;
97+ return url . pathname + url . search ;
98+ }
99+
91100 addEventListener < TEvent extends WebSocketEventType > (
92101 event : TEvent ,
93102 callback : EventHandler < TData , TEvent > ,
@@ -174,6 +183,7 @@ export class ReconnectingWebSocket<TData = unknown>
174183
175184 const socket = await this . #socketFactory( ) ;
176185 this . #currentSocket = socket ;
186+ this . #lastRoute = this . #route;
177187
178188 socket . addEventListener ( "open" , ( event ) => {
179189 this . #backoffMs = this . #options. initialBackoffMs ;
@@ -193,7 +203,7 @@ export class ReconnectingWebSocket<TData = unknown>
193203 const errorMessage = event . error ?. message ?? event . message ?? "" ;
194204 if ( this . isUnrecoverableHttpError ( errorMessage ) ) {
195205 this . #logger. error (
196- `Unrecoverable HTTP error for ${ this . #apiRoute } : ${ errorMessage } ` ,
206+ `Unrecoverable HTTP error for ${ this . #route } : ${ errorMessage } ` ,
197207 ) ;
198208 this . suspend ( ) ;
199209 }
@@ -247,7 +257,7 @@ export class ReconnectingWebSocket<TData = unknown>
247257 const delayMs = Math . max ( 0 , this . #backoffMs + jitter ) ;
248258
249259 this . #logger. debug (
250- `Reconnecting WebSocket in ${ Math . round ( delayMs ) } ms for ${ this . #apiRoute } ` ,
260+ `Reconnecting WebSocket in ${ Math . round ( delayMs ) } ms for ${ this . #route } ` ,
251261 ) ;
252262
253263 this . #reconnectTimeoutId = setTimeout ( ( ) => {
@@ -267,7 +277,7 @@ export class ReconnectingWebSocket<TData = unknown>
267277 handler ( eventData ) ;
268278 } catch ( error ) {
269279 this . #logger. error (
270- `Error in ${ event } handler for ${ this . #apiRoute } ` ,
280+ `Error in ${ event } handler for ${ this . #route } ` ,
271281 error ,
272282 ) ;
273283 }
@@ -285,17 +295,14 @@ export class ReconnectingWebSocket<TData = unknown>
285295
286296 if ( this . isUnrecoverableHttpError ( error ) ) {
287297 this . #logger. error (
288- `Unrecoverable HTTP error during connection for ${ this . #apiRoute } ` ,
298+ `Unrecoverable HTTP error during connection for ${ this . #route } ` ,
289299 error ,
290300 ) ;
291301 this . suspend ( ) ;
292302 return ;
293303 }
294304
295- this . #logger. warn (
296- `WebSocket connection failed for ${ this . #apiRoute} ` ,
297- error ,
298- ) ;
305+ this . #logger. warn ( `WebSocket connection failed for ${ this . #route} ` , error ) ;
299306 this . scheduleReconnect ( ) ;
300307 }
301308
0 commit comments