Skip to content

Commit c16e42d

Browse files
helielsonnodkz
authored andcommitted
fix(cacheMiddleware): do not cache responses with errors by default (#35)
* [cacheMiddleware] Do not cache responses with errors * Add option on cacheMiddleware to allow store errors * Update README.
1 parent 2aefb95 commit c16e42d

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ import { RelayNetworkLayer } from 'react-relay-network-modern/es';
9191
* `allowMutations` - allow to cache Mutation requests (default: `false`)
9292
* `allowFormData` - allow to cache FormData requests (default: `false`)
9393
* `clearOnMutation` - clear the cache on any Mutation (default: `false`)
94+
* `cacheErrors` - cache responses with errors (default: `false`)
9495
* **authMiddleware** - for adding auth token, and refreshing it if gets 401 response from server.
9596
* `token` - string which returns token. Can be function(req) or Promise. If function is provided, then it will be called for every request (so you may change tokens on fly).
9697
* `tokenRefreshPromise`: - function(req, res) which must return promise or regular value with a new token. This function is called when server returns 401 status code. After receiving a new token, middleware re-run query to the server seamlessly for Relay.

src/__mocks__/mockReq.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type RelayResponse from '../RelayResponse';
66

77
type ReqData = {
88
query?: string,
9-
varaibles?: Object,
9+
variables?: Object,
1010
files?: any,
1111
};
1212

@@ -36,7 +36,7 @@ class MockReq {
3636
}
3737
3838
getVariables(): Object {
39-
return this.reqData.varaibles || {};
39+
return this.reqData.variables || {};
4040
}
4141
4242
getFiles(): any {

src/middlewares/__tests__/cache-test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,46 @@ describe('middlewares/cache', () => {
142142
expect(res2.data).toBe('PAYLOAD');
143143
expect(fetchMock.calls('/graphql')).toHaveLength(2);
144144
});
145+
146+
it('do not use cache for responses with errors', async () => {
147+
fetchMock.mock({
148+
matcher: '/graphql',
149+
response: {
150+
status: 200,
151+
body: { data: 'PAYLOAD', errors: [{ type: 'timeout' }] },
152+
},
153+
method: 'POST',
154+
});
155+
156+
const rnl = new RelayNetworkLayer([cacheMiddleware()]);
157+
158+
// try fetch
159+
await expect(mockReq('FirstQuery').execute(rnl)).rejects.toThrow();
160+
expect(fetchMock.calls('/graphql')).toHaveLength(1);
161+
162+
// try fetch again
163+
await expect(mockReq('FirstQuery').execute(rnl)).rejects.toThrow();
164+
expect(fetchMock.calls('/graphql')).toHaveLength(2);
165+
});
166+
167+
it('use cache for responses with errors and cacheErrors flag', async () => {
168+
fetchMock.mock({
169+
matcher: '/graphql',
170+
response: {
171+
status: 200,
172+
body: { data: 'PAYLOAD', errors: [{ type: 'timeout' }] },
173+
},
174+
method: 'POST',
175+
});
176+
177+
const rnl = new RelayNetworkLayer([cacheMiddleware({ cacheErrors: true })]);
178+
179+
// try fetch
180+
await expect(mockReq('FirstQuery').execute(rnl)).rejects.toThrow();
181+
expect(fetchMock.calls('/graphql')).toHaveLength(1);
182+
183+
// try fetch again
184+
await expect(mockReq('FirstQuery').execute(rnl)).rejects.toThrow();
185+
expect(fetchMock.calls('/graphql')).toHaveLength(1);
186+
});
145187
});

src/middlewares/cache.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ type CacheMiddlewareOpts = {|
1111
allowMutations?: boolean,
1212
allowFormData?: boolean,
1313
clearOnMutation?: boolean,
14+
cacheErrors?: boolean,
1415
|};
1516

1617
export default function queryMiddleware(opts?: CacheMiddlewareOpts): Middleware {
17-
const { size, ttl, onInit, allowMutations, allowFormData, clearOnMutation } = opts || {};
18+
const { size, ttl, onInit, allowMutations, allowFormData, clearOnMutation, cacheErrors } = opts || {};
1819
const cache = new QueryResponseCache({
1920
size: size || 100, // 100 requests
2021
ttl: ttl || 15 * 60 * 1000, // 15 minutes
@@ -43,7 +44,9 @@ export default function queryMiddleware(opts?: CacheMiddlewareOpts): Middleware
4344
const variables = req.getVariables();
4445
const res = await next(req);
4546

46-
cache.set(queryId, variables, res);
47+
if (!res.errors || (res.errors && cacheErrors)) {
48+
cache.set(queryId, variables, res);
49+
}
4750
return res;
4851
}
4952

@@ -57,7 +60,9 @@ export default function queryMiddleware(opts?: CacheMiddlewareOpts): Middleware
5760
}
5861

5962
const res = await next(req);
60-
cache.set(queryId, variables, res);
63+
if (!res.errors || (res.errors && cacheErrors)) {
64+
cache.set(queryId, variables, res);
65+
}
6166

6267
return res;
6368
} catch (e) {

0 commit comments

Comments
 (0)