mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
fix(app-error): auto-recover from stale-shell ChunkLoadError
After a deploy the cached SPA shell still references the old chunk filenames. Next.js fetches them, the new server 404s the request, and the user sees the generic error surface — typically with no context other than "Failed to load chunk". The fix on the user's side is a hard reload; before this commit they had to discover it themselves. `AppError` now detects the chunk-load family of errors (`ChunkLoadError`, `Loading chunk`, `Failed to load chunk`, `Failed to fetch dynamically imported module`) and triggers a single `window.location.reload()`. `sessionStorage` gates the auto-reload to once per session so an unrecoverable error doesn't loop into a reload storm. Browsers in strict-privacy mode fall through to the error UI cleanly.
This commit is contained in:
1 parent
7c0eee788e
commit
82241063f6
1 file changed
+32
@@ -3,6 +3,19 @@
|
||||
import { useEffect } from "react";
|
||||
import { ErrorDetails } from "@/components/error-details";
|
||||
|
||||
const CHUNK_RELOAD_KEY = "healthlog:chunk-reload-attempted";
|
||||
|
||||
function isChunkLoadError(err: Error & { digest?: string }): boolean {
|
||||
if (err.name === "ChunkLoadError") return true;
|
||||
const msg = err.message ?? "";
|
||||
return (
|
||||
msg.includes("Loading chunk") ||
|
||||
msg.includes("Loading CSS chunk") ||
|
||||
msg.includes("Failed to load chunk") ||
|
||||
msg.includes("Failed to fetch dynamically imported module")
|
||||
);
|
||||
}
|
||||
|
||||
export default function AppError({
|
||||
error,
|
||||
reset,
|
||||
@@ -18,6 +31,25 @@ export default function AppError({
|
||||
};
|
||||
g.__healthlog_onError?.(error);
|
||||
}
|
||||
|
||||
// v1.4.38.3 — auto-recover from a stale-shell chunk-load error.
|
||||
// After a deploy the cached shell still references old chunk
|
||||
// filenames; they 404 and Next.js surfaces them as `ChunkLoadError`.
|
||||
// A single hard reload fetches the new shell + chunk graph.
|
||||
// sessionStorage gates the auto-reload so an error we can't recover
|
||||
// from (e.g. the new build is also missing the chunk) doesn't loop.
|
||||
if (typeof window !== "undefined" && isChunkLoadError(error)) {
|
||||
try {
|
||||
const already = window.sessionStorage.getItem(CHUNK_RELOAD_KEY);
|
||||
if (!already) {
|
||||
window.sessionStorage.setItem(CHUNK_RELOAD_KEY, String(Date.now()));
|
||||
window.location.reload();
|
||||
}
|
||||
} catch {
|
||||
// sessionStorage can throw under strict privacy modes — fall
|
||||
// through to the error UI in that case.
|
||||
}
|
||||
}
|
||||
}, [error]);
|
||||
|
||||
return <ErrorDetails error={error} reset={reset} />;
|
||||
|
||||
Reference in new issue
Block a user