Skip to content

fix(frontend): raw transport and developer errors reach users instead of friendly messages #748

Open

Description

@cristim

Summary

Raw transport and developer errors reach users ("HTTP 502", "timed out after 30000ms", "Failed to fetch", "Unexpected token '<'"), and server-provided reasons are replaced by fixed strings in several places.

Where

Reviewed commit b50ca38.

  • frontend/src/api/client.ts:243-255 (synthesises HTTP 502; produces Request to /api/... timed out after 30000ms)
  • frontend/src/api/auth.ts:296 (setupAdmin calls response.json() with no catch, so a 502 shows "Unexpected token '<'")
  • frontend/src/dashboard.ts:237 ("Failed to load dashboard: HTTP 502") plus about 15 toasts in history.ts:1345-1634, and plans.ts:87,115, history.ts:285-384, inventory.ts:129,380, apikeys.ts:397
  • Server reasons dropped for fixed strings: users/userActions.ts:152, groups/groupActions.ts:32, modules/registrations.ts:236,249, apikeys.ts:488,512; bulk override failures always say "Check your connection" (settings.ts:1998)

Failure scenario

A proxy returns 502 or the network drops: users see "HTTP 502", "Failed to fetch" or a JSON parse error, and a server-side validation reason is hidden behind a canned message. Verification level: source-level, not driven live.

User impact

Every user who hits a transient backend or network failure sees developer text with no next step; admins lose the real reason for a rejected action.

Suggested fix

Add a friendlyError(err) in utils.ts (status 0 to "Can't reach CUDly. Check your connection."; 401/403; 5xx to "CUDly is temporarily unavailable"; timeout), use it at every interpolation site, prefer the server's message when present, and render inline load failures as an error-state card with a Retry button, keeping raw detail in a <details> for support.

Related: #134 (checklist item on getPublicInfo fabricating a response; different defect), #6 (UX backlog umbrella).

Screenshots

usab-home-upcoming-500.png (in the review fleet archive at /Users/cristi/.claude/agent-comms/review-fleet-20261008/screens/, NOT uploaded).

Severity

Medium: widespread, but only on failure paths.

Reviewer ID: UX-25 (vis M2 + usab L8 + usab L9)
Found by the 2026-10-08 review fleet.

Activity

  1. IAmJSD commented on Oct 24, 2026

    @IAmJSD
    Collaborator

    Claiming: working on this

  2. self-assigned this
    on Oct 24, 2026
  3. IAmJSD commented on Oct 27, 2026

    @IAmJSD
    Collaborator

    Status update (2026-10-27, checked against main at 7b86e38): What is left is frontend UI work, which cristim owns, so no PR from us.

    friendlyError and the transport-error wrapping are on main (frontend/src/api/errors.ts). Still open: an error-state card with Retry and a

    Details block for inline load failures, and moving the remaining direct fetch() calls in frontend/src/api/auth.ts and accounts.ts, plus commitmentOptions.ts, onto the friendly-error path.

    Left / blocked on: All remaining work is frontend (cristim). There is no backend part.

  4. cristim commented on Nov 4, 2026

    @cristim
    MemberAuthor

    Another example, Opportunities page (2026-11-04): the toast "Last recommendations collection had errors: failed to insert recommendations batch: ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time (SQLSTATE 21000)" shows the raw Postgres error to the user (frontend/src/recommendations.ts, the last_collection_error toast).

  5. cristim commented on Nov 4, 2026

    @cristim
    MemberAuthor

    Two surfaces still show the raw last_collection_error after #1698 (which fixes only the refresh-outcome toast), checked at #1698's head 048042f:

    • frontend/src/recommendations.ts:388-390, the stale-on-open toast: "Last recommendations collection had errors: " (the case in the comment above).
    • frontend/src/first-run-empty-state.ts:54-55, the first-run empty state: "The last collection reported errors: ".

    Root fix: last_collection_error is built by joinProviderErrors in internal/scheduler/scheduler.go as "provider: ; ...". Storing a fixed per-provider summary there (for example "aws: collection failed"), and writing the raw error to the server log, would fix every reader at once, including any added later, instead of each UI surface separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions