fix(app): IDB invalid state error on mobile safari (#8)
This commit is contained in:
parent
84b6bb2a5b
commit
75f9afc843
@ -325,6 +325,15 @@ class AccountStorage {
|
|||||||
return name === 'DataCloneError';
|
return name === 'DataCloneError';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isInvalidStateError(error: unknown): boolean {
|
||||||
|
if (!error || typeof error !== 'object') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = (error as {name?: unknown}).name;
|
||||||
|
return name === 'InvalidStateError';
|
||||||
|
}
|
||||||
|
|
||||||
async stashAccountData(
|
async stashAccountData(
|
||||||
userId: string,
|
userId: string,
|
||||||
token: string | null,
|
token: string | null,
|
||||||
@ -388,6 +397,13 @@ class AccountStorage {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isInvalidStateError(err)) {
|
||||||
|
logger.warn(`InvalidStateError (database closing) while stashing account ${userId}; using memory store`, err);
|
||||||
|
this.memoryStore.set(userId, safeRecord);
|
||||||
|
logger.debug(`Stashed account data for ${userId} (memory fallback after InvalidStateError)`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
logger.error(`Failed to stash account data for ${userId}`, err);
|
logger.error(`Failed to stash account data for ${userId}`, err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@ -523,17 +539,26 @@ class AccountStorage {
|
|||||||
return this.memoryStore.get(userId) ?? null;
|
return this.memoryStore.get(userId) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await withTimeout(
|
try {
|
||||||
new Promise<StoredAccount | null>((resolve, reject) => {
|
return await withTimeout(
|
||||||
const tx = this.db!.transaction([STORE_NAME], 'readonly');
|
new Promise<StoredAccount | null>((resolve, reject) => {
|
||||||
const store = tx.objectStore(STORE_NAME);
|
const tx = this.db!.transaction([STORE_NAME], 'readonly');
|
||||||
const req = store.get(userId);
|
const store = tx.objectStore(STORE_NAME);
|
||||||
req.onsuccess = () => resolve((req.result as StoredAccount | undefined) ?? null);
|
const req = store.get(userId);
|
||||||
req.onerror = () => reject(req.error ?? new Error('IndexedDB get failed'));
|
req.onsuccess = () => resolve((req.result as StoredAccount | undefined) ?? null);
|
||||||
}),
|
req.onerror = () => reject(req.error ?? new Error('IndexedDB get failed'));
|
||||||
5000,
|
}),
|
||||||
'IndexedDB get account',
|
5000,
|
||||||
);
|
'IndexedDB get account',
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (this.isInvalidStateError(err)) {
|
||||||
|
logger.warn(`InvalidStateError (database closing) in getRecord for ${userId}; using memory store`, err);
|
||||||
|
return this.memoryStore.get(userId) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async putRecord(record: StoredAccount): Promise<void> {
|
private async putRecord(record: StoredAccount): Promise<void> {
|
||||||
@ -544,19 +569,29 @@ class AccountStorage {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await withTimeout(
|
try {
|
||||||
new Promise<void>((resolve, reject) => {
|
await withTimeout(
|
||||||
const tx = this.db!.transaction([STORE_NAME], 'readwrite');
|
new Promise<void>((resolve, reject) => {
|
||||||
const store = tx.objectStore(STORE_NAME);
|
const tx = this.db!.transaction([STORE_NAME], 'readwrite');
|
||||||
const req = store.put(normalized);
|
const store = tx.objectStore(STORE_NAME);
|
||||||
req.onsuccess = () => resolve();
|
const req = store.put(normalized);
|
||||||
req.onerror = () => reject(req.error ?? new Error('IndexedDB put failed'));
|
req.onsuccess = () => resolve();
|
||||||
}),
|
req.onerror = () => reject(req.error ?? new Error('IndexedDB put failed'));
|
||||||
5000,
|
}),
|
||||||
'IndexedDB put account record',
|
5000,
|
||||||
);
|
'IndexedDB put account record',
|
||||||
|
);
|
||||||
|
|
||||||
this.memoryStore.set(record.userId, normalized);
|
this.memoryStore.set(record.userId, normalized);
|
||||||
|
} catch (err) {
|
||||||
|
if (this.isInvalidStateError(err)) {
|
||||||
|
logger.warn(`InvalidStateError (database closing) in putRecord for ${record.userId}; using memory store`, err);
|
||||||
|
this.memoryStore.set(record.userId, normalized);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateLastActive(userId: string): Promise<void> {
|
private async updateLastActive(userId: string): Promise<void> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user