Skip to content

Commit

Permalink
Fallback to fetch() if the precached response is missing. (#1302)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffposnick committed Feb 14, 2018
1 parent d63d712 commit 8a1f659
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
21 changes: 18 additions & 3 deletions packages/workbox-precaching/_default.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,24 @@ moduleExports.addRoute = (options) => {
}

let responsePromise = caches.open(cacheName)
.then((cache) => {
return cache.match(precachedUrl);
});
.then((cache) => {
return cache.match(precachedUrl);
}).then((cachedResponse) => {
if (cachedResponse) {
return cachedResponse;
}

// Fall back to the network if we don't have a cached response (perhaps
// due to manual cache cleanup).
if (process.env.NODE_ENV !== 'production') {
logger.debug(`The precached response for ` +
`${getFriendlyURL(precachedUrl)} in ${cacheName} was not found. ` +
`Falling back to the network instead.`);
}

return fetch(precachedUrl);
});

if (process.env.NODE_ENV !== 'production') {
responsePromise = responsePromise.then((response) => {
// Workbox is going to handle the route.
Expand Down
33 changes: 33 additions & 0 deletions test/workbox-precaching/node/controllers/test-default.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,39 @@ describe(`[workbox-precaching] default export`, function() {
const response = await fetchPromise;
expect(response).to.not.exist;
});

it(`should call fetch() if there's a missing entry for a URL that has been precached`, async function() {
const fetchResponse = new Response('From fetch()');
const fetchStub = sandbox.stub(self, 'fetch').returns(fetchResponse);

const url = '/some-url';

let fetchCb;
sandbox.stub(self, 'addEventListener').callsFake((eventName, cb) => {
if (eventName === 'fetch') {
fetchCb = cb;
}
});

precaching.addRoute();
// Because the install handler is not called in this test, there won't be
// a cache entry for url, even though precache() is called.
precaching.precache([url]);

const fetchEvent = new FetchEvent('fetch', {
request: new Request(url),
});
let responsePromise;
fetchEvent.respondWith = (promise) => {
responsePromise = promise;
};
fetchCb(fetchEvent);

const response = await responsePromise;

expect(fetchStub.calledOnce).to.be.true;
expect(response).to.eql(fetchResponse);
});
});

describe(`precacheAndRoute()`, function() {
Expand Down

0 comments on commit 8a1f659

Please sign in to comment.