From 4410a994eff0f94f2ff673f41f4dd029df80a544 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sat, 31 Oct 2026 15:40:21 -0400 Subject: [PATCH] fix(ui): silence the two benign cancelled-transition rejections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round-4 console hygiene: fast navigation rejects with "AbortError: Transition was skipped" (the browser's MPA view transitions — @view-transition navigation:auto — when a navigation interrupts a running crossfade) and Alpine's x-transition hide rejects with {isFromCancelledTransition: true} when a re-show supersedes an out-phase. Both are races the user cannot lose anything in, but they print console errors on every quick click — and the knob matrix's zero-console-error tripwire (the thing that catches silent CSP death) depends on a clean console. A narrow global gate swallows exactly these two shapes; every other rejection still reports. --- web/src/main.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/web/src/main.ts b/web/src/main.ts index 1b74ab31..1aa4fdc7 100644 --- a/web/src/main.ts +++ b/web/src/main.ts @@ -42,5 +42,30 @@ import "./unlinked_books"; import "./websocket"; import "./woodPanelingInit"; +// ─── cancelled-view-transition noise gate (plan round-4 item 9) ──── +// Two transition races are BENIGN BY DESIGN and reject their promises +// as unhandled rejections on every fast navigation: +// - `AbortError: Transition was skipped` — the browser's MPA view +// transitions (@view-transition { navigation: auto } in input.css) +// when a new navigation interrupts the running crossfade. +// - `{isFromCancelledTransition: true}` — Alpine's x-transition hide +// cancelled by a re-show before the out-phase finished. +// Both mean "an animation was superseded", nothing was lost; the knob +// matrix's zero-console-error tripwire depends on the console staying +// CLEAN, so only these two shapes are swallowed — real rejections +// still report. +window.addEventListener("unhandledrejection", (event) => { + const reason = event.reason as + | (Error & { isFromCancelledTransition?: boolean }) + | null + | undefined; + const cancelledTransition = + reason?.isFromCancelledTransition === true || + (reason?.name === "AbortError" && /transition was skipped/i.test(reason.message ?? "")); + if (cancelledTransition) { + event.preventDefault(); + } +}); + armAuthFormRedirects(); Alpine.start();