fix(api): a write that hit a connection failure is still reported, and every failure is reported once
Deep-review round 4, the "one report per failure" contract round 3 introduced. - `req` marked gateway (502/503/504) and network failures "already reported" because they raise the connection notice. But that notice is about connectivity and removes itself on the very next answer — which every caller's own resync refetch fetches at once — so a delete that hit a keepalive reset flashed the notice and was then reported nowhere, the list still there. Only the durable reports (the error dialog, the 401 sign-out) count now; the caller says the action failed. - A connection notice the user closed swallowed every later one for the rest of the visit; it is raised again. - `req` and `uploadReq` share one failure policy (`reportFailure`). The upload copy had drifted: a 502 opened the blocking "Server error (502)" dialog and cleared a notice that was still true. - A taken Plex collection name is a structured 409, localized, and the create/rename calls are quiet: it was an English dialog plus a Hungarian toast. `notifyCollectionEditError` is gone. - The mutation onErrors that toasted unconditionally after a non-quiet request (invite approve / deny / add, demo whitelist, audit clear, scheduler, share, full history, edit, config tests, tag attach) go through `notifyActionError`; the playlist delete's hand-rolled copy of it too (it takes a level now). The user role / suspend / delete actions had no onError at all: a user deleted in another tab failed silently and stayed listed — now said, and the list refetched.
This commit is contained in:
@@ -10,30 +10,15 @@ import { notify } from "./notifications";
|
||||
* the Plex watched-toggles and the saved-view ops, and delegated to by `notifyYouTubeActionError`
|
||||
* for its non-403 case.
|
||||
*/
|
||||
export function notifyActionError(err: unknown, fallbackMessage: string): void {
|
||||
// Already on screen (`req` opened the error dialog, or raised the connection notice): a toast on
|
||||
export function notifyActionError(
|
||||
err: unknown,
|
||||
fallbackMessage: string,
|
||||
level: "error" | "warning" = "error",
|
||||
): void {
|
||||
// Already on screen (`req` opened the error dialog, or the tab is being signed out): a toast on
|
||||
// top reported one fault twice. Playlists filtered this by status by hand; the watched toggles,
|
||||
// the saved views and a playlist delete did not.
|
||||
if (alreadyReported(err)) return;
|
||||
const detail = err instanceof HttpError ? err.detail : null;
|
||||
notify({ level: "error", message: detail || fallbackMessage });
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection write errors. The backend enforces per-library name uniqueness and returns 409 on a
|
||||
* duplicate; localize that specific case to the friendly `nameTaken` copy (notifyActionError would
|
||||
* otherwise surface the server's raw English detail). Everything else falls back to the generic
|
||||
* edit-failed handling (which still prefers the server's reason when present). Both args are already
|
||||
* translated so this stays i18n-agnostic and unit-testable.
|
||||
*/
|
||||
export function notifyCollectionEditError(
|
||||
err: unknown,
|
||||
editFailedMessage: string,
|
||||
nameTakenMessage: string,
|
||||
): void {
|
||||
if (err instanceof HttpError && err.status === 409) {
|
||||
notify({ level: "error", message: nameTakenMessage });
|
||||
return;
|
||||
}
|
||||
notifyActionError(err, editFailedMessage);
|
||||
notify({ level, message: detail || fallbackMessage });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user