fix(ui): handle blocked storage getters (#1330)
Co-authored-by: Isaac Sanchez <isanchez-hawkins@arize.com>
This commit is contained in:
committed by
GitHub
co-authored by
Isaac Sanchez
parent
69ea4767f7
commit
5189eb586e
@@ -0,0 +1,48 @@
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
|
||||
const importSafeStorage = async () => {
|
||||
return await import(`./safeStorage.ts?test=${Date.now()}-${Math.random()}`) as typeof import('./safeStorage');
|
||||
};
|
||||
|
||||
describe('safeStorage', () => {
|
||||
test('falls back to memory when storage getters throw', async () => {
|
||||
const previousWindow = Object.getOwnPropertyDescriptor(globalThis, 'window');
|
||||
const throwingWindow = {};
|
||||
|
||||
Object.defineProperties(throwingWindow, {
|
||||
localStorage: {
|
||||
get() {
|
||||
throw new Error('localStorage blocked');
|
||||
},
|
||||
},
|
||||
sessionStorage: {
|
||||
get() {
|
||||
throw new Error('sessionStorage blocked');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Object.defineProperty(globalThis, 'window', {
|
||||
configurable: true,
|
||||
value: throwingWindow,
|
||||
});
|
||||
|
||||
try {
|
||||
const { getSafeSessionStorage, getSafeStorage } = await importSafeStorage();
|
||||
const storage = getSafeStorage();
|
||||
const sessionStorage = getSafeSessionStorage();
|
||||
|
||||
storage.setItem('local-key', 'local-value');
|
||||
sessionStorage.setItem('session-key', 'session-value');
|
||||
|
||||
expect(storage.getItem('local-key')).toBe('local-value');
|
||||
expect(sessionStorage.getItem('session-key')).toBe('session-value');
|
||||
} finally {
|
||||
if (previousWindow) {
|
||||
Object.defineProperty(globalThis, 'window', previousWindow);
|
||||
} else {
|
||||
delete (globalThis as { window?: unknown }).window;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,18 @@
|
||||
let safeStorageInstance: Storage | null = null;
|
||||
let safeSessionStorageInstance: Storage | null = null;
|
||||
|
||||
const getWindowStorage = (key: 'localStorage' | 'sessionStorage'): Storage | null => {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return window[key] ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const createInMemoryStorage = (): Storage => {
|
||||
const store = new Map<string, string>();
|
||||
return {
|
||||
@@ -22,11 +34,12 @@ const createInMemoryStorage = (): Storage => {
|
||||
};
|
||||
|
||||
const createSafeStorage = (): Storage => {
|
||||
if (typeof window === 'undefined' || !window.localStorage) {
|
||||
const baseStorage = getWindowStorage('localStorage');
|
||||
|
||||
if (!baseStorage) {
|
||||
return createInMemoryStorage();
|
||||
}
|
||||
|
||||
const baseStorage = window.localStorage;
|
||||
const fallback = createInMemoryStorage();
|
||||
let storageAvailable = true;
|
||||
|
||||
@@ -123,11 +136,12 @@ export const getSafeStorage = (): Storage => {
|
||||
};
|
||||
|
||||
const createSafeSessionStorage = (): Storage => {
|
||||
if (typeof window === 'undefined' || !window.sessionStorage) {
|
||||
const baseStorage = getWindowStorage('sessionStorage');
|
||||
|
||||
if (!baseStorage) {
|
||||
return createInMemoryStorage();
|
||||
}
|
||||
|
||||
const baseStorage = window.sessionStorage;
|
||||
const fallback = createInMemoryStorage();
|
||||
let storageAvailable = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user