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 @@

Something failed

+ + diff --git a/static/js/boot-diagnostics.js b/static/js/boot-diagnostics.js new file mode 100644 index 00000000..8a3e885e --- /dev/null +++ b/static/js/boot-diagnostics.js @@ -0,0 +1,130 @@ +// Catch and show a failure that happens while the app is wiring itself up. +// +// main.js wires the UI in a long synchronous run of wireX() calls and only +// registers its own error handlers near the end of the module. A throw anywhere +// in that run therefore 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 that is +// the engine's own behaviour, but whose buttons and file drop do nothing, +// because nothing is listening. Nothing is written anywhere (#618, found via +// #617). +// +// This module exists to be the thing that still works when that happens, so it +// follows three rules: +// +// 1. It is loaded BEFORE main.js in index.html. Module scripts execute in +// document order, so its handlers are installed before main.js is +// evaluated and are in place for anything main.js does, including a +// failure to parse or to resolve an import. +// 2. It imports nothing. An import is a second thing that can fail, and it +// would fail in exactly the circumstances this module needs to survive. +// 3. It styles itself inline. It cannot rely on a stylesheet having loaded, +// and CSP allows inline style (`style-src 'self' 'unsafe-inline'`) while +// forbidding inline script, which is also why this is a file rather than a +//