@@ -140,28 +140,40 @@ export default class MessagesSubscribe extends ChatBaseCommand {
140140 // Close Ably client properly with timeout
141141 await this . properlyCloseAblyClient ( ) ;
142142
143- return super . finally ( err ) ;
143+ // Ensure the process does not linger due to any stray async handles
144+ await super . finally ( err ) ;
145+
146+ // Force a graceful exit shortly after cleanup to avoid hanging (skip in tests)
147+ if ( process . env . NODE_ENV !== 'test' ) {
148+ setTimeout ( ( ) => {
149+ process . exit ( 0 ) ;
150+ } , 100 ) ;
151+ }
144152 }
145153
146154 async run ( ) : Promise < void > {
147155 const { args, flags } = await this . parse ( MessagesSubscribe ) ;
148156 this . roomId = args . roomId ; // Store for cleanup
157+ this . logCliEvent ( flags , "subscribe.run" , "start" , `Starting rooms messages subscribe for room: ${ this . roomId } ` ) ;
149158
150159 try {
151160 // Always show the readiness signal first, before attempting auth
152161 if ( ! this . shouldOutputJson ( flags ) ) {
153162 this . log ( `${ chalk . dim ( "Listening for messages. Press Ctrl+C to exit." ) } ` ) ;
154163 }
164+ this . logCliEvent ( flags , "subscribe.run" , "initialSignalLogged" , "Initial readiness signal logged." ) ;
155165
156166 // Try to create clients, but don't fail if auth fails
157167 try {
168+ this . logCliEvent ( flags , "subscribe.auth" , "attemptingClientCreation" , "Attempting to create Chat and Ably clients." ) ;
158169 // Create Chat client
159170 this . chatClient = await this . createChatClient ( flags ) as ChatClientType ;
160171 // Also get the underlying Ably client for cleanup and state listeners
161172 this . ablyClient = await this . createAblyClient ( flags ) ;
173+ this . logCliEvent ( flags , "subscribe.auth" , "clientCreationSuccess" , "Chat and Ably clients created." ) ;
162174 } catch ( authError ) {
163- // Auth failed, but we still want to show the signal and wait
164- this . logCliEvent ( flags , "initialization" , "authFailed" , `Authentication failed: ${ authError instanceof Error ? authError . message : String ( authError ) } ` ) ;
175+ const errorMsg = authError instanceof Error ? authError . message : String ( authError ) ;
176+ this . logCliEvent ( flags , "initialization" , "authFailed" , `Authentication failed: ${ errorMsg } ` , { error : errorMsg } ) ;
165177 if ( ! this . shouldOutputJson ( flags ) ) {
166178 this . log ( `Connected to room: ${ this . roomId || args . roomId } (mock)` ) ;
167179 this . log ( "Listening for messages" ) ;
@@ -242,19 +254,9 @@ export default class MessagesSubscribe extends ChatBaseCommand {
242254 ) ;
243255
244256 // Get the room
245- this . logCliEvent (
246- flags ,
247- "room" ,
248- "gettingRoom" ,
249- `Getting room handle for ${ this . roomId } ` ,
250- ) ;
257+ this . logCliEvent ( flags , "room" , "gettingRoom" , `Getting room handle for ${ this . roomId } ` ) ;
251258 const room = await this . chatClient . rooms . get ( this . roomId , { } ) ;
252- this . logCliEvent (
253- flags ,
254- "room" ,
255- "gotRoom" ,
256- `Got room handle for ${ this . roomId } ` ,
257- ) ;
259+ this . logCliEvent ( flags , "room" , "gotRoom" , `Got room handle for ${ this . roomId } ` ) ;
258260
259261 // Setup message handler
260262 this . logCliEvent (
@@ -317,24 +319,13 @@ export default class MessagesSubscribe extends ChatBaseCommand {
317319 ) ;
318320
319321 // Subscribe to room status changes
320- this . logCliEvent (
321- flags ,
322- "room" ,
323- "subscribingToStatus" ,
324- `Subscribing to status changes for room ${ this . roomId } ` ,
325- ) ;
322+ this . logCliEvent ( flags , "room" , "subscribingToStatus" , `Subscribing to status changes for room ${ this . roomId } ` ) ;
326323 this . unsubscribeStatusFn = room . onStatusChange (
327324 ( statusChange : unknown ) => {
328- // Type assertion after we receive it
329325 const change = statusChange as StatusChange ;
330- this . logCliEvent (
331- flags ,
332- "room" ,
333- `status-${ change . current } ` ,
334- `Room status changed to ${ change . current } ` ,
335- { reason : change . reason , roomId : this . roomId } ,
336- ) ;
326+ this . logCliEvent ( flags , "room" , `status-${ change . current } ` , `Room status changed to ${ change . current } ` , { reason : change . reason , roomId : this . roomId } ) ;
337327 if ( change . current === "attached" ) {
328+ this . logCliEvent ( flags , "room" , "statusAttached" , "Room status is ATTACHED." ) ;
338329 if ( ! this . shouldSuppressOutput ( flags ) ) {
339330 if ( this . shouldOutputJson ( flags ) ) {
340331 // Already logged via logCliEvent
@@ -344,6 +335,7 @@ export default class MessagesSubscribe extends ChatBaseCommand {
344335 ) ;
345336 // Output the exact signal that E2E tests expect (without ANSI codes)
346337 this . log ( "Listening for messages" ) ;
338+ this . logCliEvent ( flags , "room" , "readySignalLogged" , "Final readiness signal 'Listening for messages' logged." ) ;
347339 this . log (
348340 `${ chalk . dim ( "Press Ctrl+C to exit." ) } ` ,
349341 ) ;
@@ -368,13 +360,9 @@ export default class MessagesSubscribe extends ChatBaseCommand {
368360 ) ;
369361
370362 // Attach to the room
371- this . logCliEvent (
372- flags ,
373- "room" ,
374- "attaching" ,
375- `Attaching to room ${ this . roomId } ` ,
376- ) ;
363+ this . logCliEvent ( flags , "room" , "attaching" , `Attaching to room ${ this . roomId } ` ) ;
377364 await room . attach ( ) ;
365+ this . logCliEvent ( flags , "room" , "attachCallComplete" , `room.attach() call complete for ${ this . roomId } . Waiting for status change to 'attached'.` ) ;
378366 // Note: successful attach logged by onStatusChange handler
379367
380368 this . logCliEvent (
0 commit comments