🐛 Fix stale-asset detector missing protocol-dispatch errors

The stale-asset-error? predicate only matched keyword-constant
cross-build mismatches ($cljs$cst$). Protocol dispatch failures
($cljs$core$I prefix, e.g. IFn/ISeq) and V8's 'Cannot read
properties of undefined' phrasing were not covered, so the handler
fell through to a generic toast instead of triggering a hard reload.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
Andrey Antukh 2026-04-07 14:01:13 +00:00
parent 9a0ae32488
commit 52f28a1eee

View File

@ -43,16 +43,33 @@
(defn stale-asset-error?
"Returns true if the error matches the signature of a cross-build
module mismatch: accessing a ClojureScript keyword constant that
doesn't exist on the shared $APP object."
module mismatch. Two distinct patterns can appear depending on which
cross-module reference is accessed first:
1. Keyword constants names contain '$cljs$cst$'; these arise when a
compiled keyword defined in shared.js is absent in the version of
shared.js already resident in the browser.
2. Protocol dispatch names contain '$cljs$core$I'; these arise when
main-workspace.js (new build) tries to invoke a protocol method on
an object whose prototype was stamped by an older shared.js that
used different mangled property names (e.g. the LazySeq /
instaparse crash: 'Cannot read properties of undefined (reading
\\'$cljs$core$IFn$_invoke$arity$1$\\')').
Both patterns are symptoms of the same split-brain deployment
scenario (browser has JS chunks from two different builds) and
should trigger a hard page reload."
[cause]
(when (some? cause)
(let [message (ex-message cause)]
(and (string? message)
(str/includes? message "$cljs$cst$")
(or (str/includes? message "$cljs$cst$")
(str/includes? message "$cljs$core$I"))
(or (str/includes? message "is undefined")
(str/includes? message "is null")
(str/includes? message "is not a function"))))))
(str/includes? message "is not a function")
(str/includes? message "Cannot read properties of undefined"))))))
(defn exception->error-data
[cause]