From c53086b06d2a005a1d78b73652b409338277e91b Mon Sep 17 00:00:00 2001 From: Thales <> Date: Sat, 12 Sep 2026 02:47:18 +0100 Subject: [PATCH] Say why the app did not start, instead of showing a dead one main.js wires the UI in a synchronous run of fifteen wireX() calls and only registers its own error handlers at the end of the module. A throw anywhere in that run does two things at once: every listener after it never attaches, and the handlers that would have reported it never register either. What the user gets is an app that hovers and lets them type, because the engine does that itself, but whose buttons and file drop do nothing because nothing is listening. Nothing is written anywhere. There was no earlier error capture in the frontend, and CSP script-src 'self' forbids adding an inline one to the HTML. boot-diagnostics.js is loaded before main.js and shows the failure in the page. It follows three rules so it still works when main.js does not: it imports nothing, since an import is a second thing that can fail in exactly these circumstances; it styles itself inline, since it cannot assume a stylesheet loaded; and it listens in the capture phase, because a module that 404s fires its error on the element and never bubbles to window. Its strings are English and do not go through i18n. That is deliberate and is the one place in the UI where it is correct: i18n.js is itself a module that can fail to load, and a banner that renders nothing when translation is broken defeats the point of having it. One honest limit, asserted in the tests rather than papered over: when a dependency 404s, the banner names main.js and not the missing file. The module loader fetches dependencies itself, so no per-file error event exists to catch. Which file is missing is a uvicorn access line in backend.log, which is why the banner points at /api/logs/backend rather than pretending to know. Four browser tests cover a module that fails to load, a throw during wiring, that the detail is selectable and the banner dismissable, and that a healthy page shows nothing. The first three fail without the script tag; verified by removing it. Refs #618, and the investigation behind #617. --- static/index.html | 3 + static/js/boot-diagnostics.js | 130 ++++++++++++++++++++++++++++++++ tests/e2e/boot-failure.spec.mjs | 83 ++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 static/js/boot-diagnostics.js create mode 100644 tests/e2e/boot-failure.spec.mjs diff --git a/static/index.html b/static/index.html index d7862198..5db0a9ab 100644 --- a/static/index.html +++ b/static/index.html @@ -1087,6 +1087,9 @@