I am using the caching facility of service workers, however, after an update to the site, the cache still serves the old data when I refresh the page.
So as per the answer in this post I implemented the stale-while-revalidate:
self.addEventListener('fetch', function(event) {
event.respondWith(caches.open(CACHE_NAME).then(function(cache) {
return cache.match(event.request).then(function(response) {
var fetchPromise = fetch(event.request).then(function(networkResponse) {
// if we got a response from the cache, update the cache
if (response) {
console.log("cached page: " + event.request.url);
cache.put(event.request, networkResponse.clone());
}
return networkResponse;
});
// respond from the cache, or the network
return response || fetchPromise;
});
}));
});
While connected, all seems well, and I can see the console log message.
When I stop the server and refresh the page I get a load of exceptions.
Uncaught (in promise) TypeError: Failed to fetch
Failed to load resource: net::ERR_CONNECTION_REFUSED
I added a catch on the fetch() to try and handle the exceptions but it still fails (and the catch is not called). I added a catch on the caches.open() and respondWith() but same thing.
I know I can ignore these errors, but I'd rather handle them and do nothing (including not outputing them to the console) so I can see the meaningful stuff in the console I am outputting.
How can I stop the error messages?
The error when the service installs is less of a probem, but that would also be nice to catch and ignore.
Adding in a no-op .catch() to the end of your fetch() promise chain should prevent the Uncaught (in promise) TypeError: Failed to fetch message from being logged:
var fetchPromise = fetch(event.request).then(function(networkResponse) {
// if we got a response from the cache, update the cache
if (response) {
console.log("cached page: " + event.request.url);
cache.put(event.request, networkResponse.clone());
}
return networkResponse;
}).catch(function() {
// Do nothing.
});
I know you mentioned that you tried to add in a .catch(), but perhaps it wasn't located on the correct part of the chain?
I'm not aware of any way to prevent the Failed to load resource: net::ERR_CONNECTION_REFUSED message from being logged, as that comes directly from Chrome's native networking code. There's nothing you could "handle" from JavaScript.
I did put the catch where you had it, I even tried again, but still errors. The key turned out to be a second function to the then() call.
This was the eventually working code. There was also a bug in the initial response handling from the post I cut and paste. This one works for me.
self.addEventListener('fetch', function(event) {
event.respondWith(caches.open(CACHE_NAME).then(function(cache) {
return cache.match(event.request).then(function(response) {
//console.log("cache request: " + event.request.url);
var fetchPromise = fetch(event.request).then(function(networkResponse) {
// if we got a response from the cache, update the cache
//console.log("fetch completed: " + event.request.url, networkResponse);
if (networkResponse) {
//console.debug("updated cached page: " + event.request.url, networkResponse);
cache.put(event.request, networkResponse.clone());
}
return networkResponse;
}, function (e) {
// rejected promise - just ignore it, we're offline
//console.log("Error in fetch()", e);
;
});
// respond from the cache, or the network
return response || fetchPromise;
});
}));
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With