Skip to content

feat: surface connection/auth/RPC errors instead of spinning#93

Merged
antfu merged 3 commits into
mainfrom
feat/connection-error-surfacing
Jul 15, 2026
Merged

feat: surface connection/auth/RPC errors instead of spinning#93
antfu merged 3 commits into
mainfrom
feat/connection-error-surfacing

Conversation

@antfubot

Copy link
Copy Markdown
Collaborator

Why

When the devframe client couldn't reach the server, was refused auth, or lost the socket mid-session, the UI just spun with no feedback — it was never clear what was happening. Root causes:

  • `connectDevframe` resolved as soon as `__connection.json` was read, then ran the WebSocket connect + trust handshake in the background with no way to observe the outcome.
  • The only client event was `rpc:is-trusted:updated`; the transport's `onConnected`/`onError`/`onDisconnected` hooks were never wired to the client.
  • birpc ran with `timeout: -1`, so any call made before trust or on a dead/refused socket never settled → an infinite spinner.
  • Auth rejection (`isTrusted: false`) silently left the trust gate waiting.

What

devframe client (core)

  • A single connection status model — `connecting` / `connected` / `unauthorized` / `disconnected` / `error` — exposed as `rpc.status` + `rpc.connectionError`, driven from the WebSocket lifecycle and the trust handshake.
  • New events on the client: `connection:status`, `connection:error`, `rpc:error` (plus the existing `rpc:is-trusted:updated`).
  • A `DevframeConnectionError` (with `kind: 'connection' | 'auth' | 'timeout'`) so a UI can tailor its message.
  • RPC calls now fail fast instead of hanging: in-flight and new calls reject when the socket closes or trust is refused, with an opt-in `callTimeout`.
  • No automatic reconnection (by design) — reload is the recovery path.

@devframes/hub

  • The client's connection status is exposed centrally on `DevframeClientContext` (`context.connection`), so a viewer can render one indicator for all docked plugins.

Built-in plugins

  • git (React), inspect (Vue), terminals (Svelte), code-server (vanilla) and messages (Vue) render a consistent connecting / disconnected / unauthorized / error state with a reload affordance, replacing the infinite spinners.
  • a11y (Solid) keeps its BroadcastChannel-first UI (the backend is optional there) and surfaces a degraded backend as a quiet tag.

Verification

`pnpm lint && pnpm test && pnpm typecheck && pnpm build` all pass. Added focused client tests covering the status transitions, fail-fast-on-disconnect, and timeout behavior; regenerated the affected tsnapi API snapshots.

This PR was created with the help of an agent.

antfubot added 2 commits July 15, 2026 06:59
Add a single connection status model (connecting/connected/unauthorized/
disconnected/error) plus connection:status/connection:error/rpc:error events
and a DevframeConnectionError to the devframe client, wired from the WebSocket
lifecycle and the trust handshake. In-flight and new RPC calls now reject when
the socket drops or trust is refused (with an optional callTimeout) instead of
hanging forever, so a UI can show why it isn't loading rather than spinning.
Expose the status centrally on the hub client context.
Every built-in plugin now renders a clear connection state — connecting,
disconnected, unauthorized, or error, with a reload affordance — driven by the
devframe client's status, replacing the indefinite spinners that appeared when
the socket dropped or auth was refused. git (React), inspect (Vue), terminals
(Svelte), code-server (vanilla) and messages (Vue) gate their surface on the
status; a11y (Solid) keeps its BroadcastChannel-first UI and surfaces a
degraded backend as a quiet tag.
@netlify

netlify Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploy Preview for devfra ready!

Name Link
🔨 Latest commit 3a7b402
🔍 Latest deploy log https://app.netlify.com/projects/devfra/deploys/6a57425b6ddc6a000840dc72
😎 Deploy Preview https://deploy-preview-93--devfra.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Add a 'Handling connection and auth errors' section to the client guide
covering rpc.status, rpc.connectionError, the connection:status /
connection:error / rpc:error events, DevframeConnectionError (and its kind),
and the callTimeout option, with one framework-neutral recipe that gates the
UI on status and branches a failing call on error kind. Refresh the now-stale
Events section and options table, and note that a hub viewer can read the same
status centrally via context.connection.
@antfu antfu merged commit d984ae6 into main Jul 15, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants