Skip to content

Commit

Permalink
fix(core): Check for storage initialization errors
Browse files Browse the repository at this point in the history
  • Loading branch information
cwomack committed Oct 18, 2024
1 parent bf58ebc commit 3e3c873
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 9 deletions.
30 changes: 30 additions & 0 deletions packages/core/__tests__/storage/DefaultStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,34 @@ describe('DefaultStorage', () => {
await defaultStorage.clear();
expect(defaultStorage.getItem(key)).resolves.toBeNull();
});

it('should fall back to alternative storage when localStorage is not accessible', async () => {
// Mock window.localStorage to throw an error
const originalLocalStorage = window.localStorage;
Object.defineProperty(window, 'localStorage', {
get: () => {
throw new Error('localStorage is not accessible');
},
});

console.error = jest.fn(); // Mock console.error

// Create a new DefaultStorage instance to trigger the fallback
const fallbackStorage = new DefaultStorage();

// Verify that the storage still works as expected
await fallbackStorage.setItem(key, value);
expect(await fallbackStorage.getItem(key)).toEqual(value);

// Verify that the error was logged
expect(console.error).toHaveBeenCalledWith(
'LocalStorage access failed:',
expect.any(Error),
);

// Restore the original localStorage
Object.defineProperty(window, 'localStorage', {
value: originalLocalStorage,
});
});
});
32 changes: 31 additions & 1 deletion packages/core/__tests__/storage/SessionStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SessionStorage } from '../../src/storage/SessionStorage';
const key = 'k';
const value = 'value';

describe('sessionStorage', () => {
describe('SessionStorage', () => {
let sessionStorage: SessionStorage;

beforeEach(() => {
Expand Down Expand Up @@ -37,4 +37,34 @@ describe('sessionStorage', () => {
await sessionStorage.clear();
expect(await sessionStorage.getItem(key)).toBeNull();
});

it('should fall back to alternative storage when sessionStorage is not accessible', async () => {
// Mock window.sessionStorage to throw an error
const originalSessionStorage = window.sessionStorage;
Object.defineProperty(window, 'sessionStorage', {
get: () => {
throw new Error('sessionStorage is not accessible');
},
});

console.error = jest.fn(); // Mock console.error

// Create a new SessionStorage instance to trigger the fallback
const fallbackStorage = new SessionStorage();

// Verify that the storage still works as expected
await fallbackStorage.setItem(key, value);
expect(await fallbackStorage.getItem(key)).toEqual(value);

// Verify that the error was logged
expect(console.error).toHaveBeenCalledWith(
'SessionStorage access failed:',
expect.any(Error),
);

// Restore the original sessionStorage
Object.defineProperty(window, 'sessionStorage', {
value: originalSessionStorage,
});
});
});
36 changes: 28 additions & 8 deletions packages/core/src/storage/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,36 @@ import { InMemoryStorage } from './InMemoryStorage';
* @internal
* @returns Either a reference to window.localStorage or an in-memory storage as fallback
*/
export const getLocalStorageWithFallback = (): Storage =>
typeof window !== 'undefined' && window.localStorage
? window.localStorage
: new InMemoryStorage();
export const getLocalStorageWithFallback = (): Storage => {
try {
// Attempt to use localStorage directly
if (typeof window !== 'undefined' && window.localStorage) {
return window.localStorage;
}
} catch (e) {
// Handle any errors related to localStorage access
console.error('LocalStorage access failed:', e);
}

// Return in-memory storage as a fallback if localStorage is not accessible
return new InMemoryStorage();
};

/**
* @internal
* @returns Either a reference to window.sessionStorage or an in-memory storage as fallback
*/
export const getSessionStorageWithFallback = (): Storage =>
typeof window !== 'undefined' && window.sessionStorage
? window.sessionStorage
: new InMemoryStorage();
export const getSessionStorageWithFallback = (): Storage => {
try {
// Attempt to use sessionStorage directly
if (typeof window !== 'undefined' && window.sessionStorage) {
return window.sessionStorage;
}
} catch (e) {
// Handle any errors related to sessionStorage access
console.error('SessionStorage access failed:', e);
}

// Return in-memory storage as a fallback if sessionStorage is not accessible
return new InMemoryStorage();
};

0 comments on commit 3e3c873

Please sign in to comment.