From 40d3fb2ce570163386828c0628ed3f03638e6714 Mon Sep 17 00:00:00 2001 From: kuekhaoyang Date: Mon, 24 Nov 2025 16:43:22 +0800 Subject: [PATCH] feat: Improve service worker error propagation for m3u8 manifests and segments by explicitly throwing errors and returning non-200 responses. --- public/sw.js | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/public/sw.js b/public/sw.js index 4617c4f..6f94d24 100644 --- a/public/sw.js +++ b/public/sw.js @@ -30,17 +30,27 @@ self.addEventListener('fetch', (event) => { if (url.pathname.endsWith('.m3u8')) { event.respondWith( caches.open(CACHE_NAME).then((cache) => { - return cache.match(event.request, { ignoreSearch: true }).then((response) => { + return cache.match(event.request, { ignoreSearch: true }).then((cachedResponse) => { // Always fetch fresh manifest but return cached while fetching const fetchPromise = fetch(event.request).then((networkResponse) => { - if (networkResponse && networkResponse.status === 200) { - cache.put(event.request, networkResponse.clone()); + // Check if network response is valid + if (!networkResponse || networkResponse.status !== 200) { + throw new Error('Network response was not ok'); } + cache.put(event.request, networkResponse.clone()); return networkResponse; - }).catch(() => response); // Fallback to cache on network error + }).catch((err) => { + // If network fails, return cached response if available + if (cachedResponse) { + return cachedResponse; + } + // If no cache and network fails, throw error so browser handles it + // This allows the client (VideoPlayer) to catch the error and retry with proxy + throw err; + }); // Return cache immediately if available, otherwise wait for network - return response || fetchPromise; + return cachedResponse || fetchPromise; }); }) ); @@ -61,10 +71,14 @@ self.addEventListener('fetch', (event) => { // Only cache valid responses if (response && response.status === 200) { cache.put(event.request, response.clone()); + return response; } + // If response is not valid (e.g. 403, 404), return it as is + // so the browser/player can handle the error status return response; }).catch((error) => { console.error('[SW] Failed to fetch segment:', error); + // Throw error to let browser handle it throw error; }); });