GoogleChrome / workbox

📦 Workbox: JavaScript libraries for Progressive Web Apps
https://developers.google.com/web/tools/workbox/
MIT License
12.34k stars 814 forks source link

Uncaught (in promise) TypeError: Failed to fetch in Strategy #2761

Closed gfoidl closed 3 years ago

gfoidl commented 3 years ago

Library Affected: workbox-strategies 6.1.0 (webpack v4 with inject plugin)

Browser & Platform: Gooble Chrome Version 88.0.4324.182

Issue or Feature Request Description: The error should not be uncaught, as the strategy delivers a result.

It's not a public web-app, so sorry that I can't share an url. Basically it's just a backend-server with a REST-based API, and the frontend witht the service-worker.

The service-worker registers for the API's GET a route with network-first strategy:

const apiGetHandler = new NetworkFirst({
    cacheName: "Foo-Web-api-get",
    plugins  : [
        new ExpirationPlugin({
            purgeOnQuotaError: true,
            maxEntries       : 500
        })
    ]
});
registerRoute(/\/api\//, apiGetHandler, "GET");
service worker code (full) ```ts import { clientsClaim, setCacheNameDetails } from "workbox-core"; import { BackgroundSyncPlugin } from "workbox-background-sync"; import { ExpirationPlugin } from "workbox-expiration"; import { cleanupOutdatedCaches, precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching"; import { NavigationRoute, registerRoute } from "workbox-routing"; import { NetworkFirst, NetworkOnly } from "workbox-strategies"; declare const self: ServiceWorkerGlobalScope; self.skipWaiting(); clientsClaim(); setCacheNameDetails({ prefix: "Foo-Web", suffix: "" }); const networkFirstStrategy = new NetworkFirst(); registerRoute(/^\/(index.html)?$/, networkFirstStrategy); const apiGetHandler = new NetworkFirst({ cacheName: "Foo-Web-api-get", plugins : [ new ExpirationPlugin({ purgeOnQuotaError: true, maxEntries : 500 }) ] }); registerRoute(/\/api\//, apiGetHandler, "GET"); const backgroundSync = new BackgroundSyncPlugin("Foo-Web_BG_Sync", { maxRetentionTime: 24 * 60 }); const apiPostAndPutHandler = new NetworkOnly({ plugins: [ backgroundSync ] }); registerRoute(/\/api\//, apiPostAndPutHandler, "POST"); registerRoute(/\/api\//, apiPostAndPutHandler, "PUT"); cleanupOutdatedCaches(); precacheAndRoute(self.__WB_MANIFEST); // SPA-route const spaHandler = createHandlerBoundToURL("/index.html"); const navigationRoute = new NavigationRoute(spaHandler); registerRoute(navigationRoute); ```

Making a call to the API while being online looks in the logs like:

grafik

So the response gets cached. Then going offline and making the call again logs:

grafik

workbox retrieves the response from the cache (as expected)

grafik

but the uncaught error shouldn't happen.

In workbox v5 the uncaught error didn't occur. I saw the release-notes and the part about precaching being a real route now, so I tried moving the registrations around, but nothing mitigated the uncaught error.

jeffposnick commented 3 years ago

What you're seeing is expected, especially when using the development bundles of Workbox that includes extra logging. Hopefully the next few lines of logging where Workbox says that it was unable to get the response from the network and is therefore falling back to the cache makes it clear what's going on.

It's that exception during the fetch() that triggers the fallback to the cache, and we explicitly re-throw it when we encounter it, so I don't think we want to change that logic: https://github.com/GoogleChrome/workbox/blob/80be8b16aba62fa927e5c3c19e55f8d16a78e808/packages/workbox-strategies/src/Strategy.ts#L193-L195

gfoidl commented 3 years ago

we explicitly re-throw it when we encounter it

Thanks for clarification!

huykon commented 1 year ago

I am still facing with issue like this, could anyone can take a look to help me image