This commit is contained in:
+15
-1
@@ -1,8 +1,22 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { PageHeader } from "@/components/general/PageHeader";
|
||||
import { isChunkLoadError } from "@/lib/chunkError";
|
||||
|
||||
const RELOAD_KEY = "chunk-error-reload";
|
||||
const RELOAD_COOLDOWN_MS = 10_000;
|
||||
|
||||
function ErrorPage({ error }: { error: Error & { digest?: string } }) {
|
||||
useEffect(() => {
|
||||
if (!isChunkLoadError(error)) return;
|
||||
// No reload loop if the chunk is gone for good
|
||||
const last = Number(sessionStorage.getItem(RELOAD_KEY) ?? 0);
|
||||
if (Date.now() - last < RELOAD_COOLDOWN_MS) return;
|
||||
sessionStorage.setItem(RELOAD_KEY, String(Date.now()));
|
||||
window.location.reload();
|
||||
}, [error]);
|
||||
|
||||
function ErrorPage() {
|
||||
return (
|
||||
<main className="site-main" id="main">
|
||||
<div>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { isChunkLoadError } from "./chunkError.ts";
|
||||
|
||||
describe("isChunkLoadError", () => {
|
||||
it("matches the turbopack chunk loader error", () => {
|
||||
const error = new Error(
|
||||
"Failed to load chunk /_next/static/chunks/0xd_vh2ud8yl-.js from module 64893"
|
||||
);
|
||||
error.name = "ChunkLoadError";
|
||||
expect(isChunkLoadError(error)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches by message when the name is generic", () => {
|
||||
expect(isChunkLoadError(new Error("Loading chunk 123 failed."))).toBe(true);
|
||||
expect(
|
||||
isChunkLoadError(
|
||||
new TypeError("Failed to fetch dynamically imported module: https://neuf.no/x.js")
|
||||
)
|
||||
).toBe(true);
|
||||
expect(isChunkLoadError(new TypeError("Importing a module script failed."))).toBe(true);
|
||||
});
|
||||
|
||||
it("ignores other errors", () => {
|
||||
expect(isChunkLoadError(new Error("boom"))).toBe(false);
|
||||
expect(
|
||||
isChunkLoadError(new TypeError("Cannot read properties of undefined (reading 'slug')"))
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
// A tab opened before a deploy may reference chunks the new build no longer ships
|
||||
export function isChunkLoadError(error: Error): boolean {
|
||||
return (
|
||||
error.name === "ChunkLoadError" ||
|
||||
/failed to load chunk|loading chunk .* failed|dynamically imported module|importing a module script failed/i.test(
|
||||
error.message
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user