Failing to activate SW and returning failed fetch promises
pmbanugo opened this issue · 3 comments
I have my SW implemented as shown
importScripts("/resources/sw-toolbox.js");
const version = "0.12";
self.addEventListener("install", function(event){
event.waitUntil(
caches.open(version)
.then(function(cache){
return cache.addAll(["/index.html",
"/",
"/history.html",
"/manifest.json",
"/resources/mdl/material.indigo-pink.min.css",
"/resources/mdl/material.min.js",
"/resources/mdl/MaterialIcons-Regular.woff2",
"/resources/mdl/material-icons.css",
"/css/style.css",
"/resources/dialog-polyfill/dialog-polyfill.js",
"/resources/dialog-polyfill/dialog-polyfill.css",
"/js/transpiled/index.js",
"/js/transpiled/history.js",
"/js/transpiled/shared.js",
"/hoodie/client.js"]);
})
.then((r) => {
console.log("SW skipping wait");
self.skipWaiting();
console.log("SW Installed");
return r;
})
.catch(console.error));
});
self.addEventListener("activate", function (event){
console.log("SW claiming");
self.clients.claim();
console.log("SW activated");
event.waitUntil(
caches.keys()
.then(function (keys){
return Promise.all(keys.filter(function (key) {
return key !== version;
}).map(function (key) {
return caches.delete(key);
}));
})
.then((r) => {
console.log(r);
return r;
})
.catch(console.error));
});
toolbox.router.get("/hoodie/client.js", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/hoodie/*", toolbox.networkOnly);
toolbox.router.get("/*", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
I'm using Hoodie, a JS library which uses PouchDB behind the scene and when I authenticate a user with it, it continuously tries to sync data.
Because I want to use cacheFirst for every call to my domain using toolbox.router.get("/*", toolbox.cacheFirst
but then allow calls to hoodie API to pass through the network toolbox.router.get("/hoodie/*", toolbox.networkOnly);
, I have implemented my sw as such. But then it seems that when I have a new SW, the call to /hoodie/store/api/...
fails and show an error in the dev tools saying the promise rejected. A couple of rejected fetch request get's shown before the SW activates after a succesful install. Sometimes even it take a while to enter the installing event.
If I take off the statement toolbox.router.get("/hoodie/*", toolbox.networkOnly);
and then list the files and directories I want to use cache first for, it works as I expect without problem installing and activating.
toolbox.router.get("/hoodie/client.js", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
//toolbox.router.get("/hoodie/*", toolbox.networkOnly);
// toolbox.router.get("/*", toolbox.cacheFirst, {
// cache: {
// name: version,
// maxAgeSeconds: 60 * 60 * 24 * 365
// }
// });
toolbox.router.get("/", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/index.html", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/history.html", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/manifest.json", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/resources/*", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/css/*", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
toolbox.router.get("/js/*", toolbox.cacheFirst, {
cache: {
name: version,
maxAgeSeconds: 60 * 60 * 24 * 365
}
});
Is this an issue with using toolbox.networkOnly
? I was reading this
Is there a better way to arrange the registrations?
Am I misunderstanding something or is it sw-toolbox error?
Is this how service worker works?
self.addEventListener('install', (event) => {
console.info('Event: Install');
event.waitUntil(
caches.open(cacheName)
.then((cache) => {
//[] of files to cache & if any of the file not present `addAll` will fail
return cache.addAll(files)
.then(() => {
console.info('All files are cached');
return self.skipWaiting(); //To forces the waiting service worker to become the active service worker
})
.catch((error) => {
console.error('Failed to cache', error);
})
})
);
});
self.addEventListener('fetch', (event) => {
console.info('Event: Fetch');
var request = event.request;
//Tell the browser to wait for newtwork request and respond with below
event.respondWith(
//If request is already in cache, return it
caches.match(request).then((response) => {
if (response) {
return response;
}
//if request is not cached, add it to cache
return fetch(request).then((response) => {
var responseToCache = response.clone();
caches.open(cacheName).then((cache) => {
cache.put(request, responseToCache).catch((err) => {
console.warn(request.url + ': ' + err.message);
});
});
return response;
});
})
);
});
/*
ACTIVATE EVENT: triggered once after registering, also used to clean up caches.
*/
//Adding `activate` event listener
self.addEventListener('activate', (event) => {
console.info('Event: Activate');
//Remove old and unwanted caches
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cache) => {
if (cache !== cacheName) { //cacheName = 'cache-v1'
return caches.delete(cache); //Deleting the cache
}
})
);
})
);
});
try this code and i had a variable 'files' where i had the array of all the files that i wanted to cache.basically change the variable accordingly in this code
self.addEventListener('fetch', (event) => {
console.info('Event: Fetch');
var request = event.request;
//Tell the browser to wait for newtwork request and respond with below
event.respondWith(
//If request is already in cache, return it
caches.match(request).then((response) => {
if (response) {
return response;
}
//if request is not cached, add it to cache
return fetch(request).then((response) => {
var responseToCache = response.clone();
caches.open(cacheName).then((cache) => {
cache.put(request, responseToCache).catch((err) => {
console.warn(request.url + ': ' + err.message);
});
});
return response;
});
})
);
});
with that it means I'll cache every request, doens't it?
I'm suspecting the toolbox.networkOnly
behaves in a way that causes request to fail when service worker is installig
What is the solution to this issue? I have similar issue.