From 8a50538275ff2afd329516eb871565bd54113a5a Mon Sep 17 00:00:00 2001 From: npeter83 Date: Sun, 13 Sep 2026 01:45:28 +0200 Subject: [PATCH] fix(ui): a write that fails says what failed and why, wherever it fails `req` opens its blocking dialog for 400/409/422/5xx only. A 403/404/429 was left to the caller and a 502-504 or lost connection got just the self-clearing connection notice, so 34 mutations without a reporting onError and 15 direct api writes with a bare or missing catch failed in silence: a hidden channel that snapped back, a share link that never revoked, a confirmed account delete that ended with nothing said. - lib/queryClient: one MutationCache reporter. react-query awaits it BEFORE the mutation's own onError, so it waits a task and skips a failure the site already reported; the toast title comes from `meta.failTitle`, `meta.errorShownInline` opts out. - notifyActionError: title names WHAT failed, the line under it says WHY (`failureReason`: a structured localized detail, else the status). It marks the error reported (`markReported`), so nothing reports one failure twice; `notifyKnownFailure` for a site's own specific sentence. - Every silent site named (45 new HU/EN titles, 4 reasons). Stale "the global dialog shows it" comments corrected on the job actions, channel block, Plex sync, cookies, download enqueue, account delete and usePref. - Channels passed the tag hook's channel id to the reporter as the error; the tag and priority hooks now report themselves, with the real error. - A contract test keeps every useMutation naming its failure; CLAUDE.md gains the pattern row. - history.dom.test: the "navigates only once the entries are back" assertion raced an async act's macrotask flush (1 in 5 runs); it now asserts from a later popstate listener. --- CLAUDE.md | 1 + frontend/src/App.tsx | 11 +- frontend/src/components/AccountPanel.tsx | 14 +-- .../src/components/AdminUsers.dom.test.tsx | 3 +- frontend/src/components/AdminUsers.tsx | 31 ++---- frontend/src/components/ChannelPage.tsx | 37 ++++--- frontend/src/components/Channels.tsx | 8 +- frontend/src/components/DownloadCenter.tsx | 7 +- frontend/src/components/DownloadDialog.tsx | 8 +- frontend/src/components/Feed.tsx | 32 ++++-- .../src/components/NotificationsPanel.tsx | 24 +++- frontend/src/components/OnboardingWizard.tsx | 2 + .../src/components/Playlists.dom.test.tsx | 2 +- frontend/src/components/Playlists.tsx | 18 +-- frontend/src/components/PlaylistsRail.tsx | 1 + frontend/src/components/PlexSidebar.tsx | 12 +- frontend/src/components/ProfileEditor.tsx | 2 + frontend/src/components/Scheduler.tsx | 4 + frontend/src/components/SettingsPanel.tsx | 18 ++- frontend/src/components/ShareDialog.tsx | 4 + frontend/src/components/Stats.tsx | 5 + frontend/src/components/SyncStatus.tsx | 6 + frontend/src/components/TagManager.tsx | 1 + .../WriteFailureReporting.dom.test.tsx | 24 +++- .../src/components/accountPanel.dom.test.tsx | 6 +- frontend/src/components/downloadAdmin.tsx | 2 + frontend/src/components/downloadModals.tsx | 1 + .../usePlaylistActions.dom.test.tsx | 9 +- frontend/src/i18n/locales/en/errors.json | 52 +++++++++ frontend/src/i18n/locales/hu/errors.json | 52 +++++++++ frontend/src/lib/actionErrors.test.ts | 75 ++++++++++++- frontend/src/lib/actionErrors.ts | 68 +++++++++--- frontend/src/lib/api/core.ts | 8 ++ .../src/lib/channelWriteFailures.dom.test.tsx | 83 ++++++++++++++ frontend/src/lib/history.dom.test.ts | 20 +++- .../src/lib/mutationFailures.contract.test.ts | 77 +++++++++++++ frontend/src/lib/queryClient.dom.test.ts | 104 ++++++++++++++++++ frontend/src/lib/queryClient.ts | 42 +++++++ frontend/src/lib/useChannelPriority.ts | 9 +- frontend/src/lib/useChannelTagActions.ts | 17 ++- frontend/src/lib/usePref.dom.test.ts | 7 +- .../src/lib/usePref.saveFailure.dom.test.ts | 51 +++++++++ frontend/src/lib/usePref.ts | 16 ++- frontend/src/lib/youtubeErrors.ts | 2 + frontend/src/main.tsx | 7 +- 45 files changed, 851 insertions(+), 132 deletions(-) create mode 100644 frontend/src/lib/channelWriteFailures.dom.test.tsx create mode 100644 frontend/src/lib/mutationFailures.contract.test.ts create mode 100644 frontend/src/lib/queryClient.dom.test.ts create mode 100644 frontend/src/lib/queryClient.ts create mode 100644 frontend/src/lib/usePref.saveFailure.dom.test.ts diff --git a/CLAUDE.md b/CLAUDE.md index caca1a13..af4f1665 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -91,6 +91,7 @@ CQRS, a repository/DI framework, a router library, a generic CRUD-router factory | FE keyboard shortcut | a row in `lib/keymap.ts` + `dispatch()` | a private `keydown` listener with its own key literals | | FE control | the chip/segmented primitives (`Select` only for >6 options) | a native `