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 safeStorageInstance: Storage | null = null;
|
||||||
let safeSessionStorageInstance: 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 createInMemoryStorage = (): Storage => {
|
||||||
const store = new Map<string, string>();
|
const store = new Map<string, string>();
|
||||||
return {
|
return {
|
||||||
@@ -22,11 +34,12 @@ const createInMemoryStorage = (): Storage => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createSafeStorage = (): Storage => {
|
const createSafeStorage = (): Storage => {
|
||||||
if (typeof window === 'undefined' || !window.localStorage) {
|
const baseStorage = getWindowStorage('localStorage');
|
||||||
|
|
||||||
|
if (!baseStorage) {
|
||||||
return createInMemoryStorage();
|
return createInMemoryStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseStorage = window.localStorage;
|
|
||||||
const fallback = createInMemoryStorage();
|
const fallback = createInMemoryStorage();
|
||||||
let storageAvailable = true;
|
let storageAvailable = true;
|
||||||
|
|
||||||
@@ -123,11 +136,12 @@ export const getSafeStorage = (): Storage => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createSafeSessionStorage = (): Storage => {
|
const createSafeSessionStorage = (): Storage => {
|
||||||
if (typeof window === 'undefined' || !window.sessionStorage) {
|
const baseStorage = getWindowStorage('sessionStorage');
|
||||||
|
|
||||||
|
if (!baseStorage) {
|
||||||
return createInMemoryStorage();
|
return createInMemoryStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseStorage = window.sessionStorage;
|
|
||||||
const fallback = createInMemoryStorage();
|
const fallback = createInMemoryStorage();
|
||||||
let storageAvailable = true;
|
let storageAvailable = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user