fix: handle QuotaExceededError in tripSyncManager with progressive eviction

When IDB storage is full, syncTrip() throws an AbortError wrapping
QuotaExceededError. Now: clear that trip's existing data and retry once;
if quota is still exceeded, wipe all IDB data so the next sync starts
fresh rather than silently failing on every subsequent call.
This commit is contained in:
jubnl
2026-05-05 19:21:52 +02:00
parent 2ae4a18466
commit 83cba5a9ef
+25 -1
View File
@@ -27,6 +27,7 @@ import {
upsertCategories,
upsertSyncMeta,
clearTripData,
clearAll,
} from '../db/offlineDb'
import { prefetchTilesForTrip } from './tilePrefetcher'
import { useSettingsStore } from '../store/settingsStore'
@@ -69,6 +70,14 @@ function isPhoto(file: TripFile): boolean {
return file.mime_type.startsWith('image/')
}
function isQuotaError(err: unknown): boolean {
if (!(err instanceof Error)) return false
if (err.name === 'QuotaExceededError') return true
// Dexie wraps IDB errors: AbortError with inner QuotaExceededError
const inner = (err as { inner?: unknown }).inner
return inner instanceof Error && inner.name === 'QuotaExceededError'
}
// ── Core logic ────────────────────────────────────────────────────────────────
/** Fetch bundle + write all entities for one trip into Dexie. */
@@ -149,7 +158,22 @@ export const tripSyncManager = {
try {
await syncTrip(trip.id)
} catch (err) {
console.error(`[tripSync] failed for trip ${trip.id}:`, err)
if (isQuotaError(err)) {
console.warn(`[tripSync] quota exceeded for trip ${trip.id}, clearing trip data and retrying`)
try {
await clearTripData(trip.id)
await syncTrip(trip.id)
} catch (retryErr) {
if (isQuotaError(retryErr)) {
console.warn('[tripSync] quota still exceeded after eviction — clearing all IDB data')
await clearAll()
return
}
console.error(`[tripSync] failed for trip ${trip.id} after eviction:`, retryErr)
}
} else {
console.error(`[tripSync] failed for trip ${trip.id}:`, err)
}
}
}