fix(ui): recover from corrupt chunk reload markers (#1230)

* fix(ui): recover from corrupt chunk reload markers

* test(ui): clarify chunk recovery assertions

---------

Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
This commit is contained in:
Isaac Sanchez-Hawkins
2026-05-12 11:00:58 +03:00
committed by GitHub
co-authored by Isaac Sanchez
parent eeabc304bd
commit 416a11dcce
3 changed files with 70 additions and 4 deletions
@@ -0,0 +1,51 @@
import { describe, expect, test } from 'bun:test';
import { importWithChunkRecovery } from './chunkLoadRecovery';
describe('importWithChunkRecovery', () => {
test('schedules recovery reload when stored reload marker is corrupt', async () => {
const globalWithWindow = globalThis as unknown as { window?: unknown };
const previousWindow = globalWithWindow.window;
let storedMarker: string | null = null;
let reloadCount = 0;
globalWithWindow.window = {
sessionStorage: {
getItem: () => '{not json',
setItem: (_key: string, value: string) => {
storedMarker = value;
},
},
setTimeout: (callback: () => void) => {
callback();
return 0;
},
location: {
reload: () => {
reloadCount += 1;
},
},
};
try {
let caught: unknown;
try {
await importWithChunkRecovery(async () => {
throw new Error('Failed to fetch dynamically imported module');
}, { retries: 0 });
} catch (error) {
caught = error;
}
expect(caught).toBeInstanceOf(Error);
expect(storedMarker).not.toBeNull();
expect(reloadCount).toBe(1);
} finally {
if (previousWindow === undefined) {
delete globalWithWindow.window;
} else {
globalWithWindow.window = previousWindow;
}
}
});
});
+17 -4
View File
@@ -46,13 +46,26 @@ function scheduleReloadOnce(error: unknown): void {
const now = Date.now();
const signature = reloadMarkerSignature(error);
let marker: { signature?: unknown; timestamp?: unknown } | null = null;
try {
const rawMarker = window.sessionStorage.getItem(RELOAD_STORAGE_KEY);
const marker = rawMarker ? JSON.parse(rawMarker) as { signature?: unknown; timestamp?: unknown } : null;
const markerTimestamp = typeof marker?.timestamp === 'number' ? marker.timestamp : 0;
if (marker?.signature === signature && now - markerTimestamp < RELOAD_GUARD_MS) {
return;
if (rawMarker) {
try {
marker = JSON.parse(rawMarker) as { signature?: unknown; timestamp?: unknown };
} catch {
marker = null;
}
}
} catch {
return;
}
const markerTimestamp = typeof marker?.timestamp === 'number' ? marker.timestamp : 0;
if (marker?.signature === signature && now - markerTimestamp < RELOAD_GUARD_MS) {
return;
}
try {
window.sessionStorage.setItem(RELOAD_STORAGE_KEY, JSON.stringify({ signature, timestamp: now }));
} catch {
return;
+2
View File
@@ -15,10 +15,12 @@ declare module "bun:test" {
toBeGreaterThan(expected: number): void;
toBeLessThan(expected: number): void;
toHaveLength(expected: number): void;
toBeInstanceOf(expected: unknown): void;
not: {
toEqual(expected: unknown): void;
toBe(expected: unknown): void;
toContain(expected: unknown): void;
toBeNull(): void;
};
};
export function beforeEach(fn: () => void | Promise<void>): void;