fix: auto-recover from stale-bundle chunk errors; responsive touch-ups
- The "This page couldn't load" after a redeploy was a stale bundle: a tab open across a deploy requests JS chunks that no longer exist (ChunkLoadError). Added a global error/unhandledrejection guard that reloads once to fetch the fresh bundle (sessionStorage-guarded against loops, cleared after a healthy run). - Reaction tray width → w-[min(270px,86vw)] so it never overflows narrow phones. Verified: tsc + next build pass; web image rebuilt on :1500. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,32 @@ export default function Page() {
|
||||
const init = useSessionStore((s) => s.init);
|
||||
const loading = useSessionStore((s) => s.loading);
|
||||
|
||||
// Auto-recover from stale-bundle chunk errors (a tab open across a redeploy
|
||||
// requests JS chunks that no longer exist → "page couldn't load"). Reload once
|
||||
// to fetch the fresh bundle; clear the guard after a healthy run.
|
||||
useEffect(() => {
|
||||
const isChunkErr = (m: string) =>
|
||||
/ChunkLoadError|Loading chunk|Failed to fetch dynamically imported|error loading dynamically imported|importing a module script failed/i.test(m);
|
||||
const onErr = (e: ErrorEvent | PromiseRejectionEvent) => {
|
||||
const msg =
|
||||
((e as ErrorEvent).message ?? "") +
|
||||
" " +
|
||||
(((e as PromiseRejectionEvent).reason as { message?: string })?.message ?? "");
|
||||
if (isChunkErr(msg) && !sessionStorage.getItem("hokm.chunkReload")) {
|
||||
sessionStorage.setItem("hokm.chunkReload", "1");
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
window.addEventListener("error", onErr);
|
||||
window.addEventListener("unhandledrejection", onErr);
|
||||
const clear = setTimeout(() => sessionStorage.removeItem("hokm.chunkReload"), 5000);
|
||||
return () => {
|
||||
window.removeEventListener("error", onErr);
|
||||
window.removeEventListener("unhandledrejection", onErr);
|
||||
clearTimeout(clear);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
init();
|
||||
|
||||
|
||||
@@ -822,7 +822,7 @@ function Reactions() {
|
||||
initial={{ opacity: 0, y: 12, scale: 0.95 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 12, scale: 0.95 }}
|
||||
className="absolute bottom-20 ltr:right-4 rtl:left-4 z-50 glass rounded-2xl p-2 w-[270px]"
|
||||
className="absolute bottom-20 ltr:right-4 rtl:left-4 z-50 glass rounded-2xl p-2 w-[min(270px,86vw)]"
|
||||
>
|
||||
<div className="flex gap-1 p-1 rounded-xl bg-navy-900/70 mb-2">
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user