From 6320cb14e502f752f0603a09484eaf7d651823f7 Mon Sep 17 00:00:00 2001 From: robin Date: Mon, 19 Jan 2026 11:39:40 +0100 Subject: [PATCH] fix: Service Worker always returns valid Response - Fixed fetch handler that could return undefined instead of Response - Changed from stale-while-revalidate to network-first with cache fallback - Always return proper 503 Response when offline and no cache available - Bump cache version to v21 to force SW update --- public/sw.js | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/public/sw.js b/public/sw.js index 485787a..d7a7cd5 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'whisky-vault-v20-offline'; +const CACHE_NAME = 'whisky-vault-v21-offline'; // CONFIG: Assets - Only essential files, no heavy OCR (~2MB instead of ~50MB) const STATIC_ASSETS = [ @@ -189,22 +189,33 @@ self.addEventListener('fetch', (event) => { if (isNavigation || isAsset) { event.respondWith( caches.match(event.request).then(async (cachedResponse) => { - const fetchPromise = fetchWithTimeout(event.request, 10000) - .then(async (networkResponse) => { - if (networkResponse && networkResponse.status === 200) { - const cache = await caches.open(CACHE_NAME); - cache.put(event.request, networkResponse.clone()); - } - return networkResponse; - }).catch(() => { }); + // Try network first + try { + const networkResponse = await fetchWithTimeout(event.request, 10000); + if (networkResponse && networkResponse.status === 200) { + const cache = await caches.open(CACHE_NAME); + cache.put(event.request, networkResponse.clone()); + } + return networkResponse; + } catch (networkError) { + // Network failed, fall back to cache + if (cachedResponse) { + return cachedResponse; + } - if (isNavigation) { - if (cachedResponse) return cachedResponse; - const shell = await caches.match('/'); - if (shell) return shell; + // For navigation, try to serve the app shell + if (isNavigation) { + const shell = await caches.match('/'); + if (shell) return shell; + } + + // Last resort: return a proper error response + return new Response('Offline - Resource not available', { + status: 503, + statusText: 'Service Unavailable', + headers: { 'Content-Type': 'text/plain' } + }); } - - return cachedResponse || fetchPromise || fetch(event.request); }) ); }