fix(ui): propagate connect errors to pending requests#54758
Conversation
Greptile SummaryThis PR fixes a long-standing gap in Key points:
Confidence Score: 5/5
Reviews (1): Last reviewed commit: "fix(ui): propagate connect errors to pen..." | Re-trigger Greptile |
e1b4396 to
9c5f1b8
Compare
|
Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 12:15 AM ET / 04:15 UTC. Summary PR surface: Source +3, Tests +35. Total +38 across 2 files. Reproducibility: yes. Source inspection of current main shows pendingConnectError is available during close but pending requests are rejected with a generic gateway-closed Error; the PR body also supplies after-fix production Gateway/Control UI logs. Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the refreshed UI-only fix with the Error-shape change intentionally accepted, and track gateway-client parity separately only if maintainers want that reusable-client contract. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection of current main shows pendingConnectError is available during close but pending requests are rejected with a generic gateway-closed Error; the PR body also supplies after-fix production Gateway/Control UI logs. Is this the best way to solve the issue? Yes. Reusing GatewayRequestError at the existing flushPending boundary is the narrowest maintainable Control UI fix; package-client parity is a separate contract choice, not a definite defect in this patch. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 37f96bde4d90. Label changesLabel justifications:
Evidence reviewedPR surface: Source +3, Tests +35. Total +38 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (4 earlier review cycles)
|
9c5f1b8 to
65114c9
Compare
|
ClawSweeper PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
Heads up: this PR needs to be updated against current |
65114c9 to
ad24efb
Compare
b5d05ba to
486ee76
Compare
9137018 to
b733441
Compare
Co-authored-by: RayRuan <[email protected]>
48fae09 to
b29f8fd
Compare
|
Merged via squash.
|
Summary
Before this fix, pending RPC requests on WebSocket close were always flushed with a generic
gateway closederror, discarding the structured connect error (e.g.PAIRING_REQUIRED,AUTH_TOKEN_MISMATCH). The UI could not show meaningful error messages because the error info was lost.Changes
flushErrorbefore both close/error call sites inonWsCloseGatewayRequestErrorwhenconnectErroris available, preservinggatewayCodeanddetailsgateway closederror when no structured error existsflushes pending requests with structured connect errors on closeTest Plan
PAIRING_REQUIREDconnect error propagates asGatewayRequestErrorwith correctgatewayCodeanddetailsReal behavior proof
Behavior or issue addressed: When the Control UI WebSocket connection failed with a structured error (e.g.
INVALID_REQUESTwithPAIRING_REQUIRED), pending RPC requests were always flushed with a genericError("gateway closed (4008): connect failed")instead of preserving the structured error. The UI could not distinguish between a random disconnect and an auth-required/pairing-needed state.Real environment tested: Production OpenClaw Control UI (v2026.6.1, Node.js v22, Linux) connecting to a real Gateway instance with device auth enabled. Tested with both authenticated and unauthenticated device tokens.
Exact steps or command run after this patch:
cron.listRPC request while the connection was still in connect phaseINVALID_REQUEST / PAIRING_REQUIREDcron.listrequest received aGatewayRequestErrorwithgatewayCode: "INVALID_REQUEST"anddetails: { code: "PAIRING_REQUIRED" }Evidence after fix:
Observed result after fix:
GatewayRequestErrorwith structured error info whenconnectErroris seterr.gatewayCodeis"INVALID_REQUEST"anderr.details.codeis"PAIRING_REQUIRED"— the UI can now render a specific messageError("gateway closed (1006): socket lost")flushes pending requests with structured connect errors on closepassesNot tested: None for the behavior changed by this PR. Broader unrelated gateway/typecheck failures on current main are outside this PR scope.