fix: surface network errors from user actions (#56) - #64
Conversation
Several user-initiated actions that perform a network write awaited the call without a catch, so a failed request produced only an unhandled promise rejection — the user saw no feedback and, for actions that also navigate or close a dialog on success, the UI silently did nothing. Route every such action through the existing feedback mechanisms (an error toast, or the page's existing inline error state) so no network error from a user action fails silently: - Sidebar: new page, new page from template, new folder, drag-to-root move - Note view: title, tags and priority edits - Tasks board: add lane - Task detail: visibility change, delete task - Organizations: delete org, rename org, remove member - OAuth clients: rotate secret, rotate & revoke, revoke client, remove org, revoke token, revoke all tokens, and token load on client select - Template manager: save (create/update), keeping the edit form open on failure so input isn't lost Add an API-mode E2E spec asserting an error toast appears when a page/folder create fails. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U1BmUXSKHAhMiMbtzMpCuR
|
🤖 Starting work on this now. |
|
🤖 Watch live or take over the session here: https://claude.ai/code/session_01RUFkA36Rm1mPXB5S81y3fT |
There was a problem hiding this comment.
Review: looks good — no changes requested. (Posting as a comment since GitHub won't let this account approve its own PR.)
This is a clean, well-scoped application of the codebase's existing error-feedback pattern to the previously unhandled user actions, with no unrelated changes.
I verified the fix is actually effective rather than dead code: every store method now wrapped in try/catch genuinely rejects on API failure and doesn't swallow internally — createPage/createFolder (repo.create propagates), updateNode/moveNode via optimisticWriter.update (re-throws after reverting), createLane (re-throws after rollback), and the orgs/oauth store methods (no internal catch). So the toast / inline-error paths will fire. apiErrorMessage returns the fallback for the 5xx the E2E test injects (matching its assertion) and prefers the API's own message on 4xx. The new spec's selectors (button[title="New page (default template)"], .toast.toast-error) match the real DOM.
Test coverage is light relative to the ~25 actions touched (the new spec exercises page/folder create only), but the pattern is uniform and low-risk. Notably, CI is fully green here — including e2e-api, so network-errors.spec.ts did run and pass, not just compile.
One non-blocking observation for the record: in settings/orgs/+page.svelte, a failed removeMember sets membersError, which the {#if membersLoading}{:else if membersError} block renders in place of the whole members list until reload. That follows the file's existing convention (updateMemberRole already behaves this way), so it's consistent — just flagging it as a known UX quirk, not something to fix in this PR.
|
Review posted successfully to PR #64. SummaryI reviewed PR #64 ("fix: surface network errors from user actions"). This is a clean approval — no changes requested. What I verified:
Non-blocking note left on the PR: a failed **Review U… ✅ Opened pull request: imaustink/glyph#64 |
|
🤖 Starting work on this now. |
|
🤖 Watch live or take over the session here: https://claude.ai/code/session_011qeHvVv3EdLAfMoRqUJKjq |
ai-triage pass — synced with base, re-verified, nothing else to changeFeedback reviewed: the only review on this PR is @k5s-bot's The one item the reviewer flagged — a failed What I did this run:
Deliberately not done: no code changes — the review requested none and the fix is verified green in CI (including CI is re-running on the new merge commit; the prior run was fully green. |
|
The PR is updated and SummaryI picked up PR #64 ("fix: surface network errors from user actions") and got it merge-ready. What the feedback was: The only review is @k5s-bot's — an explicit clean approval with no changes requested and no inline comments. It verified the newly-wrapped store methods actually reject on failure (so the toasts/inline-error paths fire), that What I did:
✅ Opened pull request: imaustink/glyph#64 |
Closes #56.
Problem
The issue requires that all network request errors from user actions be displayed to the user. Glyph already has a solid error-feedback system (the
notificationsStoretoast store rendered byToastContainer, plus per-page inline error state), and most user actions already use it. But an audit turned up a number of user-initiated actions thatawaita network write without any catch, so a failed request produced only an unhandled promise rejection: the user got no feedback, and for actions that navigate or close a dialog on success, the UI silently did nothing.Fix
Each of these actions now surfaces its failure through the mechanism already used elsewhere in that file — an error toast (
notificationsStore.error(...), usingapiErrorMessageto prefer the API's own 4xx message), or the page's existing inlineerrorstate where that's the local convention:Actions that were already handled (task status cycling, lane rename/reorder, deletes in the sidebar tree, share dialog, member add/role updates, etc.) are unchanged. Background/unload flushes (e.g.
pagehideautosave) are intentionally left as console-only since they aren't foreground user actions with a place to show a toast.Tests
pnpm check(svelte-check): 0 errors, 0 warningspnpm build: succeedspnpm testunit suite: passese2e/network-errors.spec.ts(API-mode only): forces the page/folder create request to fail and asserts an error toast appears.Maintainer: apply the ai-review label to this PR to request an automated code review, or the ai-triage label to have review feedback addressed and the branch brought back in sync with its base. (The automation can't label its own PR, so this needs a human.)
🤖 Generated with Claude Code