[nu-demo] UX: every island should render a polished empty/error state, never a raw stack trace #124

Closed
opened 2026-04-23 23:09:45 +00:00 by mik-tf · 1 comment
Owner

Symptom

Multiple islands currently surface raw backend errors to the user as polished-app-style red text. Examples seen during 2026-04-23 demo:

  • Rooms island: Failed to load island WASM 'room': JsValue(Error: Island not found: room (HTTP 404)) at eval (eval at <anonymous> (https://heronu.gent01.grid.tf/hero_os/ui/wasm/hero_os_app.js:551:25), <anonymous>:4:23)
  • Files / PDF / Presentations / Diagrams / Spreadsheets (before fix): Failed to list PDF: HTTP 404: Socket 'rpc.sock' not found for 'hero_office'
  • Browser island when socket missing: Waiting for hero_browser... Socket 'ui.sock' not found — service may be restarting. This page will refresh automatically. (this one is actually ok — states it's transient)
  • AI Assistant (before fix): HTTP 404: Socket 'ui.sock' not found for 'hero_agent'
  • Services island (now superseded by Router): Failed to load island: services with the full JsValue chain exposed
  • Settings > Environment (before fix): Error: expected value at line 1 column 1 — JSON parse error shown verbatim

Problem

These errors are accurate and useful to developers, but:

  1. They leak implementation details (socket paths, stack frames) to end users
  2. They look broken — a demo-class instance feels half-built when every empty archipelago screams at you
  3. Missing data vs. missing service vs. missing code are all presented identically

What we want

A consistent convention for three distinct states, per island:

State Example UX
No data yet (backend healthy, zero rows) Icon + "No rooms yet" / "No files in this context" + optional primary CTA ("New room", "Upload a file")
Backend temporarily down (socket missing, 5xx) Spinner + "Connecting to hero_voice…" with quiet auto-retry, no raw errors. Fall back to persistent "Unavailable" after N retries with a "Retry" button.
Not installed / feature-flagged off (island WASM 404, method not found) "Coming soon" or "This module isn't available on this deployment" + a link to install/enable docs

Proper fix

  1. Shared helper cratehero_archipelagos_core (or similar) exposes an <EmptyState>, <LoadingState>, and <ServiceUnavailable> component trio. Every island imports and uses these instead of writing its own <div class="error">{err}</div>.
  2. Error classification — RPC client wrapper maps common error shapes (HTTP 404 on socket, OpenRPC 'method not found', JSON parse on empty body) to semantic variants the UI can switch on.
  3. Silent auto-retry for transient backend unavailability (with bounded attempts + exponential backoff).
  4. No raw Debug-printed errors in the DOM. Log them to console, show a friendly message.

Demo workaround

None — this is cosmetic for now. The functional fixes (start the missing service, populate the seed) make most of these go away. But until the helper crate exists, every island re-implements error text ad-hoc.

Scope

This is an epic, not a single PR. Triage candidates in priority order:

  • Office suite (PDF/Diagrams/Presentations/Documents/Spreadsheets) — 5 islands, same backend, one fix
  • Media (Photos/Videos/Songs) — 3 islands
  • Rooms / Intelligence
  • Admin dashboards (Proxy/Proc/DB/Embedder/…) — at least use the same spinner and 'backend unavailable' component
  • Top-level hero_os_app WASM-missing fallback (today's Rooms 404)

Filed 2026-04-23 nu-shell demo. Signed-off-by: mik-tf

## Symptom Multiple islands currently surface raw backend errors to the user as polished-app-style red text. Examples seen during 2026-04-23 demo: - **Rooms** island: `Failed to load island WASM 'room': JsValue(Error: Island not found: room (HTTP 404)) at eval (eval at <anonymous> (https://heronu.gent01.grid.tf/hero_os/ui/wasm/hero_os_app.js:551:25), <anonymous>:4:23)` - **Files / PDF / Presentations / Diagrams / Spreadsheets** (before fix): `Failed to list PDF: HTTP 404: Socket 'rpc.sock' not found for 'hero_office'` - **Browser** island when socket missing: `Waiting for hero_browser... Socket 'ui.sock' not found — service may be restarting. This page will refresh automatically.` (this one is actually ok — states it's transient) - **AI Assistant** (before fix): `HTTP 404: Socket 'ui.sock' not found for 'hero_agent'` - **Services** island (now superseded by Router): `Failed to load island: services` with the full JsValue chain exposed - **Settings > Environment** (before fix): `Error: expected value at line 1 column 1` — JSON parse error shown verbatim ## Problem These errors are accurate and useful to developers, but: 1. They leak implementation details (socket paths, stack frames) to end users 2. They look broken — a demo-class instance feels half-built when every empty archipelago screams at you 3. Missing data vs. missing service vs. missing code are all presented identically ## What we want A consistent convention for three distinct states, per island: | State | Example UX | |---|---| | **No data yet** (backend healthy, zero rows) | Icon + "No rooms yet" / "No files in this context" + optional primary CTA ("New room", "Upload a file") | | **Backend temporarily down** (socket missing, 5xx) | Spinner + "Connecting to `hero_voice`…" with quiet auto-retry, no raw errors. Fall back to persistent "Unavailable" after N retries with a "Retry" button. | | **Not installed / feature-flagged off** (island WASM 404, method not found) | "Coming soon" or "This module isn't available on this deployment" + a link to install/enable docs | ## Proper fix 1. **Shared helper crate** — `hero_archipelagos_core` (or similar) exposes an `<EmptyState>`, `<LoadingState>`, and `<ServiceUnavailable>` component trio. Every island imports and uses these instead of writing its own `<div class="error">{err}</div>`. 2. **Error classification** — RPC client wrapper maps common error shapes (HTTP 404 on socket, OpenRPC 'method not found', JSON parse on empty body) to semantic variants the UI can switch on. 3. **Silent auto-retry** for transient backend unavailability (with bounded attempts + exponential backoff). 4. **No raw `Debug`-printed errors in the DOM**. Log them to console, show a friendly message. ## Demo workaround None — this is cosmetic for now. The functional fixes (start the missing service, populate the seed) make most of these go away. But until the helper crate exists, every island re-implements error text ad-hoc. ## Scope This is an epic, not a single PR. Triage candidates in priority order: - [ ] Office suite (PDF/Diagrams/Presentations/Documents/Spreadsheets) — 5 islands, same backend, one fix - [ ] Media (Photos/Videos/Songs) — 3 islands - [ ] Rooms / Intelligence - [ ] Admin dashboards (Proxy/Proc/DB/Embedder/…) — at least use the same spinner and 'backend unavailable' component - [ ] Top-level `hero_os_app` WASM-missing fallback (today's Rooms 404) Filed 2026-04-23 nu-shell demo. Signed-off-by: mik-tf
Author
Owner

Moved to hero_demo#15 — see lhumina_code/hero_demo#15

Moved to hero_demo#15 — see https://forge.ourworld.tf/lhumina_code/hero_demo/issues/15
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/home#124
No description provided.