fix(desktop): surface profile-switch failures instead of falling back to primary socket - #81165
fix(desktop): surface profile-switch failures instead of falling back to primary socket#81165echoes666 wants to merge 3 commits into
Conversation
… to primary socket Fixes NousResearch#81094 When switching to a secondary profile, openSecondary / ensureGatewayForProfile could silently fall back to the primary socket if the target backend's WebSocket failed to open (e.g. a manually started gateway process holding the profile's resources). This routed the user's messages to the wrong profile's backend and caused cross-profile session writes.
|
This was generated by AI during triage. Summary: Problems:
Solution: Checked against |
…rough to setActive The rethrow added in openSecondary (NousResearch#81094) was consumed by the unchanged `catch { scheduleReconnect(entry) }` in ensureGatewayForProfile, so a failed profile switch still ended at setActive(key) with a closed socket and the error never reached ensureGatewayProfile's catch — the fix did not actually surface the failure (spotted by AI triage on NousResearch#81165). Now the catch keeps the reconnect schedule (transient failures still self-heal) but re-throws, so the caller surfaces the error and skips activating a profile whose backend is unreachable.
|
Thanks for catching this — you're right, the rethrow was swallowed by the unchanged Fixed in 0882362 (pushed to this branch): the catch now keeps the reconnect schedule (transient failures still self-heal via the existing backoff) but re-throws, so Verified: |
…file Regression tests for the NousResearch#81094 rethrow: a failed secondary connect must propagate (not fall through to setActive with a closed socket) while still arming the reconnect backoff, and a successful connect activates the entry. Mocks @/hermes, @hermes/shared and window.hermesDesktop; module singletons are reset per test via closeSecondaryGateways.
|
Partial overlap with #87600, now on main: the silent-misroute half is fixed (activeGateway() returns null for missing named scopes; eviction paths restore the primary explicitly). What SURVIVES here and remains wanted: the error-surfacing UX — main's ensureGatewayForProfile still does |
Fixes #81094
Problem
When switching to a secondary profile,
openSecondary/ensureGatewayForProfilecould silently fall back to the primary socket if the target backend's WebSocket failed to open (e.g. a manually started gateway process holding the profile's resources). This routed the user's messages to the wrong profile's backend and caused cross-profile session writes.Changes
apps/desktop/src/store/gateway.ts(openSecondary): rethrow connect failures with an actionable error message instead of letting the caller's catch path fall through to the primary socket.apps/desktop/src/store/profile.ts(ensureGatewayProfile): log and rethrow the switch failure instead of silently resetting the swap target.Why fail loudly instead of retrying?
A silent fallback is strictly worse than an explicit error here: the user's message would be persisted into the wrong profile's session. Failing loudly surfaces the conflict (e.g. a manually started gateway holding the profile) and the message suggests how to resolve it. Retrying against a manually held socket would loop forever.
Notes
Replaces the previous PR #81099 (same fix, rebased onto current main; the old branch was force-pushed during a botched amend and GitHub does not allow reopening it).