From b74b59b906b0ffa0dad2be420219e4293ed0d162 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Tue, 3 Mar 2026 12:46:19 +0100 Subject: [PATCH] fix: Align subscription status mapping with tRPC state machine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tRPC subscriptions use connecting/pending/error/idle — not success. The old code mapped pending→isConnecting and waited for success (which never fires), causing AgentOutputViewer to permanently show "Connecting...". Now: connecting→isConnecting, pending→isConnected, idle→disconnected. --- .../hooks/useSubscriptionWithErrorHandling.ts | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/apps/web/src/hooks/useSubscriptionWithErrorHandling.ts b/apps/web/src/hooks/useSubscriptionWithErrorHandling.ts index 660021c..1a495b5 100644 --- a/apps/web/src/hooks/useSubscriptionWithErrorHandling.ts +++ b/apps/web/src/hooks/useSubscriptionWithErrorHandling.ts @@ -106,11 +106,23 @@ export function useSubscriptionWithErrorHandling( return; } - if (subscriptionResult.status === 'pending') { + if (subscriptionResult.status === 'connecting') { setState(prev => { - if (prev.isConnecting && prev.error === null) return prev; - return { ...prev, isConnecting: true, error: null }; + if (prev.isConnecting && !prev.isConnected && prev.error === null) return prev; + return { ...prev, isConnecting: true, isConnected: false, error: null }; }); + } else if (subscriptionResult.status === 'pending') { + reconnectAttemptsRef.current = 0; + setState(prev => { + if (prev.isConnected && !prev.isConnecting && prev.error === null && prev.reconnectAttempts === 0) return prev; + return { ...prev, isConnected: true, isConnecting: false, error: null, reconnectAttempts: 0 }; + }); + + if (reconnectTimeoutRef.current) { + clearTimeout(reconnectTimeoutRef.current); + reconnectTimeoutRef.current = null; + } + callbacksRef.current.onStarted?.(); } else if (subscriptionResult.status === 'error') { const error = subscriptionResult.error instanceof Error @@ -126,17 +138,12 @@ export function useSubscriptionWithErrorHandling( callbacksRef.current.onError?.(error); scheduleReconnect(); - } else if (subscriptionResult.status === 'success') { - reconnectAttemptsRef.current = 0; + } else if (subscriptionResult.status === 'idle') { setState(prev => { - if (prev.isConnected && !prev.isConnecting && prev.error === null && prev.reconnectAttempts === 0) return prev; - return { ...prev, isConnected: true, isConnecting: false, error: null, reconnectAttempts: 0 }; + if (!prev.isConnected && !prev.isConnecting && prev.error === null) return prev; + return { ...prev, isConnected: false, isConnecting: false, error: null }; }); - - if (reconnectTimeoutRef.current) { - clearTimeout(reconnectTimeoutRef.current); - reconnectTimeoutRef.current = null; - } + callbacksRef.current.onStopped?.(); } }, [enabled, subscriptionResult.status, subscriptionResult.error, scheduleReconnect]);