Improve logging when Chrome's offline check fails
See original GitHub issueWelcome! Please use this template for reporting bugs or requesting features. For questions about using Workbox, the best place to ask is Stack Overflow, tagged with [workbox]
: https://stackoverflow.com/questions/ask?tags=workbox
Library Affected: workbox workbox-sw, workbox-build, etc.
Browser & Platform: Google Chrome 89 E.g. Google Chrome v51.0.1 for Android, or “all browsers”.
Issue or Feature Request Description: Uncaught (in promise) TypeError: Failed to fetch
My start_url
is set to /?utm_source=web_app_manifest&utm_medium=web_app_manifest&utm_campaign=web_app_manifest
When reporting bugs, please include relevant JavaScript Console logs and links to public URLs at which the issue could be reproduced.
It also errors when deployed on a https url
My config looks like this:
import { skipWaiting, clientsClaim } from "workbox-core"
import {
cleanupOutdatedCaches,
precacheAndRoute,
matchPrecache,
} from "workbox-precaching"
import { setCatchHandler } from "workbox-routing"
import { registerRoute } from "workbox-routing"
import {
NetworkFirst,
StaleWhileRevalidate,
CacheFirst,
} from "workbox-strategies"
import { CacheableResponsePlugin } from "workbox-cacheable-response"
import { ExpirationPlugin } from "workbox-expiration"
import * as googleAnalytics from "workbox-google-analytics"
googleAnalytics.initialize()
cleanupOutdatedCaches()
precacheAndRoute(self.__WB_MANIFEST)
clientsClaim()
function cacheKeyWillBeUsed({ request }) {
const url = new URL(request.url)
url.pathname = url.pathname.replace(/\/index\.html$/, "/")
url.pathname = url.pathname.replace(/\.html$/, "/")
return url.href
}
const networkFirstStrategy = new NetworkFirst({
cacheName: "docs-cache",
fetchOptions: {
credentials: "include",
},
plugins: [{ cacheKeyWillBeUsed }],
})
// Cache page navigations (html) with a Network First strategy
registerRoute(
// Check to see if the request is a navigation to a new page
({ request }) => request.mode === 'navigate',
// Use a Network First caching strategy
new NetworkFirst({
// Put all cached files in a cache named 'pages'
cacheName: 'pages',
plugins: [
// Ensure that only requests that result in a 200 status are cached
new CacheableResponsePlugin({
statuses: [200],
}),
cacheKeyWillBeUsed
],
}),
);
// Cache CSS, JS, and Web Worker requests with a Stale While Revalidate strategy
registerRoute(
// Check to see if the request's destination is style for stylesheets, script for JavaScript, or worker for web worker
({ request }) =>
request.destination === 'style' ||
request.destination === 'script' ||
request.destination === 'worker',
// Use a Stale While Revalidate caching strategy
new StaleWhileRevalidate({
// Put all cached files in a cache named 'assets'
cacheName: 'assets',
plugins: [
// Ensure that only requests that result in a 200 status are cached
new CacheableResponsePlugin({
statuses: [200],
}),
],
}),
);
registerRoute(
/\.(?:png|jpg|jpeg|svg|gif|ico|mp4)$/,
// Use the cache if it's available.
new CacheFirst({
cacheName: "image-cache",
fetchOptions: {
credentials: "include",
},
plugins: [
new ExpirationPlugin({
// Cache only 50 images.
maxEntries: 50,
// Cache for a maximum of a day.
maxAgeSeconds: 24 * 60 * 60,
}),
],
})
)
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
registerRoute(
({ url }) => url.origin === "https://fonts.googleapis.com",
new StaleWhileRevalidate({
cacheName: "google-fonts-stylesheets",
})
)
// Cache the underlying font files with a cache-first strategy for 1 year.
registerRoute(
({ url }) => url.origin === "https://fonts.gstatic.com",
new CacheFirst({
cacheName: "google-fonts-webfonts",
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200],
}),
new ExpirationPlugin({
maxAgeSeconds: 60 * 60 * 24 * 365,
maxEntries: 30,
}),
],
})
)
// Catch routing errors, like if the user is offline
setCatchHandler(async ({ event }) => {
// Return the precached offline page if a document is being requested
if (event.request.destination === "document") {
return matchPrecache("/offline.html")
}
return Response.error()
})
addEventListener("message", (event) => {
if (event.data && event.data.type === "SKIP_WAITING") {
skipWaiting()
}
})
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:29 (17 by maintainers)
Top GitHub Comments
Also, I wanted to let folks know that separate from the issue of how Workbox logs things, we are actively working with the Chrome DevTools team to provide more context about what’s going on during the automatic offline check. Those improvements would help developers regardless of whether they’re using Workbox or not.
Sorry for the delay in getting back to you.
I think that everything is working as “expected,” but unfortunately it is a bit confusing now that the automatic offline navigation detection fires off a navigation request for your
start_url
with the network simulated as offline.I realize that you’re seeing the request failure message logged just because that’s what happens when you use a
NetworkFirst
runtime strategy and you’re offline—there’s an exception thrown when the network request fails, even though a valid response ends up being provided from the cache. So the installability criteria is met, but there’s an error logged.This came up in another GitHub issue recently, and I guess it’s more likely to cause confusion now that the automatic offline navigation detection is fired off by Chrome.
I’m going to leave this issue open to track some work that we could do to improve the logging around a failed network request when using
NetworkFirst
, just to make it clearer that the response is eventually provided. I’m also going to follow-up with the team at Chrome responsible for the automatic offline navigation detection to see if it might be possible to provide better attribution somewhere in DevTools letting developers know that the request is associated with that detection.