mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
15.98k stars 519 forks source link

MSW fails to start Mock because worker update() fails. #2006

Open lazpit opened 9 months ago

lazpit commented 9 months ago

Prerequisites

Environment check

Browsers

Chromium (Chrome, Brave, etc.), Firefox

Reproduction repository

https://codesandbox.io/p/devbox/msw-react-xx1c8

Reproduction steps

Can't make a reproduction repository, it depends if my backend is accessible. If backend is running, MSW mock starts and do his job. MSW fails to start mock with SetupWorker.start() when server is not reachable.

To reproduce, I have to stop my backend that serves assets and bundle.js resources.

Current behavior

The function that find existing registration of the service worker is trying to update it and returns fetch error below because service-worker.js resources is not accessible.

image image

getWorkerInstance.ts :

if (existingRegistration) { // When the Service Worker is registered, update it and return the reference. return existingRegistration.update().then(() => { return [ getWorkerByRegistration( existingRegistration, absoluteWorkerUrl, findWorker, ), existingRegistration, ] }) }

I'm asking, why do we need to call update() on existingRegistration before returning worker instance if worker is active ?

Expected behavior

Suggestion:

lazpit commented 9 months ago

This error seems to occur when there is a "no-cache" header when fetching service-worker.js

kettanaito commented 1 month ago

Hi, @lazpit. Thanks for reporting this.

I'm asking, why do we need to call update() on existingRegistration before returning worker instance if worker is active ?

Because the existing worker may be out-of-date, and the one you are registering now can be newer. Calling .update() will let the browser compare the current and the latest worker at the same worker URL, and if they are not the same, the latest worker will be registered and activated.

This error seems to occur when there is a "no-cache" header when fetching service-worker.js

How can you reproduce this? Afaik, you cannot control how the fetch request during .update() is performed. The browser forces that request to be non-cacheable. Can you show me an example of setting no-cache on that fetch request?


I've looked into a related issue in #2310. Since #2311, MSW will now perform the update in the background, returning the existing worker instance immediately. I like the use case you are showing this with issue, if you can please elaborate on how to reproduce it, I will make sure MSW handles update failures gracefully as well.