Skip to content

Commit

Permalink
fix: removed breaking behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurfiorette committed Jan 18, 2022
1 parent 2540c1e commit 7217eaf
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 22 deletions.
3 changes: 0 additions & 3 deletions docs/pages/per-request-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,6 @@ Enables cache to be returned if the response comes with an error, either by inva
code, network errors and etc. You can filter the type of error that should be stale by
using a predicate function.

**Note**: If this value ends up `false`, either by default or by a predicate function and
there was an error, the request cache will be purged.

**Note**: If the response is treated as error because of invalid status code _(like from
AxiosRequestConfig#invalidateStatus)_, and this ends up `true`, the cache will be
preserved over the "invalid" request. So, if you want to preserve the response, you can
Expand Down
3 changes: 0 additions & 3 deletions src/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ export type CacheProperties<R = unknown, D = unknown> = {
* status code, network errors and etc. You can filter the type of error that should be
* stale by using a predicate function.
*
* **Note**: If this value ends up `false`, either by default or by a predicate function
* and there was an error, the request cache will be purged.
*
* **Note**: If the response is treated as error because of invalid status code *(like
* from AxiosRequestConfig#invalidateStatus)*, and this ends up `true`, the cache will
* be preserved over the "invalid" request. So, if you want to preserve the response,
Expand Down
27 changes: 11 additions & 16 deletions src/interceptors/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,34 +168,29 @@ export function defaultResponseInterceptor(
// staleIfError is the number of seconds that stale is allowed to be used
(typeof staleIfError === 'number' && cache.createdAt + staleIfError > Date.now())
) {
const newCache: CachedStorageValue = {
state: 'cached',
ttl: Number(cache.data.headers[Header.XAxiosCacheStaleIfError]),
// Resolve all other requests waiting for this response
axios.waiting[config.id]?.resolve(cache.data);
delete axios.waiting[config.id];

// re-mark the cache as stale
await axios.storage.set(config.id, {
state: 'stale',
createdAt: Date.now(),
data: cache.data
};
});

const response: CacheAxiosResponse = {
return {
cached: true,
config,
id: config.id,
data: cache.data?.data,
headers: cache.data?.headers,
data: cache.data.data,
headers: cache.data.headers,
status: cache.data.status,
statusText: cache.data.statusText
};

// Resolve all other requests waiting for this response
axios.waiting[response.id]?.resolve(newCache.data);
delete axios.waiting[response.id];

// Valid response
return response;
}
}

// Reject this response and rethrows the error
await rejectResponse(config.id);
throw error;
};

Expand Down
51 changes: 51 additions & 0 deletions test/interceptors/stale-if-error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,55 @@ describe('Last-Modified handling', () => {
expect(newResponse.data).not.toBe(cache.data);
expect(newResponse.status).toBe(503);
});

it('expects that the cache is marked as stale', async () => {
const axios = setupCache(Axios.create(), {
staleIfError: true
});

const id = 'some-config-id';
const cacheData = {
data: true,
headers: {},
status: 200,
statusText: 'Ok'
};

// Fill the cache
await axios.storage.set(id, {
state: 'stale',
createdAt: Date.now(),
data: cacheData
});

const [res1, res2] = await Promise.all([
axios.get('http://unknown-url.lan:9090', {
id
}),
axios.get('http://unknown-url.lan:9090', {
id
})
]);

expect(res1).toBeDefined();
expect(res2).toBeDefined();
expect(res1.id).toBe(id);
expect(res2.id).toBe(id);
expect(res1.data).toBe(cacheData.data);
expect(res2.data).toBe(cacheData.data);
expect(res1.status).toBe(cacheData.status);
expect(res2.status).toBe(cacheData.status);
expect(res1.statusText).toBe(cacheData.statusText);
expect(res2.statusText).toBe(cacheData.statusText);
expect(res1.headers).toBe(cacheData.headers);
expect(res2.headers).toBe(cacheData.headers);
expect(res1.cached).toBe(true);
expect(res2.cached).toBe(true);

const cache = await axios.storage.get(id);

expect(cache.state).toBe('stale');
expect(typeof cache.createdAt).toBe('number');
expect(cache.data).toBe(cacheData);
});
});

0 comments on commit 7217eaf

Please sign in to comment.