fetchDidFail with StaleWhileRevalidate is not called
See original GitHub issueLibrary Affected: workbox v5.1.3 npm
Browser & Platform: Google Chrome v85
Issue or Feature Request Description:
I don’t seem to get how to run some code when a fetch in a StaleWhileRevalidate
strategy fails. I’d like to use the callback to detect offline usage, but fetchDidFail
is not called when I tick “offline” and reload the pahe. (fetchDidSucceed
works tho). Is this expected? I didn’t find any mention of that in the documentation.
Here’s an example:
const messageIfFail: WorkboxPlugin = {
fetchDidFail: async function () {
// No return expected.
// NOTE: `originalRequest` is the browser's request, `request` is the
// request after being passed through plugins with
// `requestWillFetch` callbacks, and `error` is the exception that caused
// the underlying `fetch()` to fail.
while (true) {
console.log("called");
}
// send message to client
}
}
registerRoute(
({url}) => {
return url.origin == "https://fonts.googleapis.com"
|| url.origin == "https://cdn.jsdelivr.net"
},
new StaleWhileRevalidate({
cacheName: 'cdn',
plugins: [
messageIfFail
]
})
);
Issue Analytics
- State:
- Created 3 years ago
- Comments:16 (2 by maintainers)
Top Results From Across the Web
workbox-strategies - Chrome Developers
When a strategy instance is registered with a Workbox workbox-routing. Route , this method is automatically called when the route matches.
Read more >workbox - Postprocess page content with staleWhileRevalidate
You're correct in that there's no RequestWrapper lifecycle event that corresponds to a network request being successfully returned.
Read more >Cache Storage Is Empty When Using Workbox With Cdn
An implementation of a stalewhilerevalidate request strategy. If the network request fails and there is no cache match this will When a strategy...
Read more >Keeping things fresh with stale-while-revalidate - web.dev
stale-while-revalidate helps developers balance between immediacy—loading cached content right away—and freshness—ensuring updates to the ...
Read more >ResourcePlugin | react-suspense-cache - LXSMNSYC
Called during the cache fetching and cache writing stage. ... Optional fetchDidFail. fetchDidFail: undefined | ((param: FetchDidFailParam<T>) ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
When attempting to debug this, I would suggest starting fresh from an Incognito window, and additionally, not checking Disable Cache. It sounds like you’ve made a number of changes to your SW during development, and it would be good to rule out inconsistent cache state (using the Incognito window) while also replicating what users will actually see in production (don’t check Disable Cache).
You might see a log message about a failed
fetch()
made byStaleWhileRevalidate
in development, but if the strategy uses a cached response from the Cache Storage API to satisfy the request, the “catch” handler won’t run. The “catch” handler only runs when there’s no response (fromfetch()
or Cache Storage API) that can be used by a strategy.FWIW, your code could be simplified to:
fetchDidFail
will execute when the underlyingfetch()
fails when usingStaleWhileRevalidate
, even if the strategy ends up using a response from the Cache Storage API.I see from your sample route that you’re attempting to use this with subresources loaded from a CDN, and in most cases, responses to those sorts of URLs will use long-lived
Cache-Control
headers that don’t require revalidation. So what my guess is as to what’s happening is that even when you’re offline, the underlyingfetch()
request succeeds, rather than fails, since a cache hit in the browser’s “normal” HTTP cache is sufficient, andfetch()
never ends up going against the network anyway.You can see this in action at https://glitch.com/edit/#!/upbeat-rebel-octopus?path=sw.js, where the example is for a HTTP response that has a maximum age of 20 seconds. If you go offline and try again within 20 seconds of populating the “normal” HTTP cache with a response, then the
fetch()
will be fulfilled from the HTTP cache. If you wait longer than 20 seconds, then the response in the HTTP cache will be considered too old to use without revalidation, and thefetch()
will fail when it makes the network request to revalidate.I’m going to close this for now, but if I’m misinterpreting anything, let me know and we can revisit.