fix(web): re-enable other server cards when a connection errors (#1521)#1522
Conversation
When a server's connection settled into the terminal `error` state, the other server cards stayed dimmed/`inert` (Connect toggle + actions disabled), so the user couldn't interact with any other server. `ServerCard` dims any card whose id differs from `activeServer`, and App clears `activeServerId` only on the InspectorClient `disconnect` event. A terminal `error` (a connect-time handshake failure, or a mid-session transport `onerror` that fires without an `onclose`) sets status to `error` but never dispatches `disconnect`, so `activeServerId` lingers and every other card stays inert. We can't clear `activeServerId` on error because the errored card's status, the connected header, and the connection-info modal are all keyed off it. Fix: dim the other cards only while the active session is actually live (connecting or connected). InspectorView now passes the active id to the ServerListScreen as the dim source only when `connectionStatus` is `connecting`/`connected`; once it reaches a terminal state the others re-enable. The errored card still shows its real status via the merged `servers` list, which keys off the real `activeServer`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Related to #1520 (fixes #1516). Both PRs touch
They should merge cleanly in either order; whichever lands second is worth a quick rebase check. |
|
@claude review |
|
Claude finished @cliffhall's task in 1m 39s —— View job Review — re-enable other server cards on error (#1521)
Verdict: correct, well-targeted, and well-documented fix. The change is sound and I'd be comfortable merging it. One concrete reuse suggestion and a couple of optional notes below. Why the fix is correctI traced the dim path end-to-end. Also worth noting: the active card is never self-dimmed regardless ( Suggestion: reuse the existing
|
Replace the hand-rolled `sessionLive` check with the existing `isTerminalStatus` predicate (the #1490 teardown convention) so the dim gate stays aligned with the canonical "session is over" branching and can't desync from a future status addition. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the thorough review! Applied the actionable suggestion in b4482fe: ✅ Reuse const dimCardsAgainst = isTerminalStatus(connectionStatus) ? undefined : activeServer;Added a value import for it (the existing import from that module was On the optional notes (leaving as-is, with reasoning):
|
|
@claude review |
|
Claude finished @cliffhall's task in 49s —— View job Re-review —
|
Summary
Fixes #1521. When a server's connection settled into the terminal Error state, the other server cards stayed dimmed/
inert— their Connect toggles and action buttons disabled — so the user couldn't interact with any other server.Root cause
ServerCarddims any card whose id differs fromactiveServer:activeServer(=activeServerIdinApp.tsx) is cleared only on the InspectorClientdisconnectevent (App.tsx, the effect at ~line 889). But a terminalerrorstate does not always firedisconnect:status = "error"and re-throws, dispatching onlystatusChange(InspectorClientconnect()catch), andonerrorthat fires without an accompanyingonclosedispatcheserror+statusChangeonly.In those cases
activeServerIdlingers, so every other card stays inert. We can't simply clearactiveServerIdon error — the errored card's status, the connected header, and the connection-info modal are all keyed off it.Fix
Dim the other cards only while the active session is genuinely live (
connectingorconnected).InspectorViewnow passes the active id toServerListScreenas the dim source only whenconnectionStatusisconnecting/connected; once the session reaches a terminal state (errorordisconnected) the other cards re-enable. The errored card itself still reflects its real status via the mergedserverslist, which keys off the realactiveServer— so the "Error" indicator is unaffected.One-line behavioural change; everything else (the merged status list, the connected header, the modal) keeps using the real
activeServer.Testing
InspectorView.test.tsx): withconnectionStatus === "error"andactiveServerstill set, the non-active card is notaria-disabled; withconnectionStatus === "connected"it is. Verified the test fails without the fix and passes with it.npm run validate(web): format, lint, build, 2000 unit tests pass; 370 Storybook play-function tests pass.Manual verification
Drove the app against a 3-server catalog. Confirmed the intended dimming during a live session (one connecting → the other two correctly greyed/disabled) and that cards re-enable once the session is no longer live. Note: the three error triggers I could reproduce with the test servers (stdio connect-timeout, SDK request-timeout, HTTP server kill) all fire
onclose→disconnectand self-recover via the existing reset; the persistent-error-without-disconnectstate from the issue is exercised by the unit regression test above.🤖 Generated with Claude Code