A tab left open across a release asked for a lazy chunk the server no longer has (prod: DownloadDialog 404 an hour after 0.89) and fell to the crash screen. `vite:preloadError` now reloads the tab once a minute at most; a second failure is let through to the error boundary, which now wraps every entry — the public /watch, /privacy and /terms pages crashed to a blank page.
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const fire = (): Event => {
|
|
const e = new Event("vite:preloadError", { cancelable: true });
|
|
window.dispatchEvent(e);
|
|
return e;
|
|
};
|
|
|
|
let uninstall = () => {};
|
|
|
|
describe("a lazy chunk the server no longer has", () => {
|
|
afterEach(() => uninstall());
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
sessionStorage.clear();
|
|
});
|
|
|
|
it("reloads the tab once, and says so to the error boundary", async () => {
|
|
const { installStaleBuildReload, reloadingForNewBuild } = await import("./staleBuild");
|
|
const reload = vi.fn();
|
|
uninstall = installStaleBuildReload(reload);
|
|
|
|
const e = fire();
|
|
|
|
expect(e.defaultPrevented).toBe(true);
|
|
expect(reload).toHaveBeenCalledTimes(1);
|
|
expect(reloadingForNewBuild()).toBe(true);
|
|
// The rest of the page's failed imports while the reload is under way: swallowed, no second reload.
|
|
expect(fire().defaultPrevented).toBe(true);
|
|
expect(reload).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("lets the error through when the reload a moment ago did not help", async () => {
|
|
sessionStorage.setItem("sf.staleBuildReload", String(Date.now() - 5_000));
|
|
const { installStaleBuildReload, reloadingForNewBuild } = await import("./staleBuild");
|
|
const reload = vi.fn();
|
|
uninstall = installStaleBuildReload(reload);
|
|
|
|
expect(fire().defaultPrevented).toBe(false);
|
|
expect(reload).not.toHaveBeenCalled();
|
|
expect(reloadingForNewBuild()).toBe(false);
|
|
});
|
|
});
|