Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service Worker throws uncaught errors when the server is down

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.

like image 504
Nigel Johnson Avatar asked Jun 15 '26 16:06

Nigel Johnson


2 Answers

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.

like image 60
Jeff Posnick Avatar answered Jun 19 '26 12:06

Jeff Posnick


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;
        });
    }));
});
like image 32
Nigel Johnson Avatar answered Jun 19 '26 13:06

Nigel Johnson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!