fix: Align subscription status mapping with tRPC state machine

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.
This commit is contained in:
Lukas May
2026-03-03 12:46:19 +01:00
parent c8f370583a
commit b74b59b906

View File

@@ -106,11 +106,23 @@ export function useSubscriptionWithErrorHandling(
return; return;
} }
if (subscriptionResult.status === 'pending') { if (subscriptionResult.status === 'connecting') {
setState(prev => { setState(prev => {
if (prev.isConnecting && prev.error === null) return prev; if (prev.isConnecting && !prev.isConnected && prev.error === null) return prev;
return { ...prev, isConnecting: true, error: null }; 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?.(); callbacksRef.current.onStarted?.();
} else if (subscriptionResult.status === 'error') { } else if (subscriptionResult.status === 'error') {
const error = subscriptionResult.error instanceof Error const error = subscriptionResult.error instanceof Error
@@ -126,17 +138,12 @@ export function useSubscriptionWithErrorHandling(
callbacksRef.current.onError?.(error); callbacksRef.current.onError?.(error);
scheduleReconnect(); scheduleReconnect();
} else if (subscriptionResult.status === 'success') { } else if (subscriptionResult.status === 'idle') {
reconnectAttemptsRef.current = 0;
setState(prev => { setState(prev => {
if (prev.isConnected && !prev.isConnecting && prev.error === null && prev.reconnectAttempts === 0) return prev; if (!prev.isConnected && !prev.isConnecting && prev.error === null) return prev;
return { ...prev, isConnected: true, isConnecting: false, error: null, reconnectAttempts: 0 }; return { ...prev, isConnected: false, isConnecting: false, error: null };
}); });
callbacksRef.current.onStopped?.();
if (reconnectTimeoutRef.current) {
clearTimeout(reconnectTimeoutRef.current);
reconnectTimeoutRef.current = null;
}
} }
}, [enabled, subscriptionResult.status, subscriptionResult.error, scheduleReconnect]); }, [enabled, subscriptionResult.status, subscriptionResult.error, scheduleReconnect]);