Skip to content
This repository has been archived by the owner on Dec 10, 2021. It is now read-only.

Commit

Permalink
feat: add retry to callApi
Browse files Browse the repository at this point in the history
  • Loading branch information
erik_ritter committed Apr 20, 2020
1 parent fb9cce3 commit 28915a2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
1 change: 1 addition & 0 deletions packages/superset-ui-connection/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"dependencies": {
"@babel/runtime": "^7.1.2",
"fetch-retry": "^3.1.0",
"whatwg-fetch": "^3.0.0"
},
"publishConfig": {
Expand Down
15 changes: 13 additions & 2 deletions packages/superset-ui-connection/src/callApi/callApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import 'whatwg-fetch';
import { CallApi } from '../types';
import { CACHE_AVAILABLE, CACHE_KEY, HTTP_STATUS_NOT_MODIFIED, HTTP_STATUS_OK } from '../constants';
import fetchRetry from 'fetch-retry';

const RETRY_COUNT = 3;
const RETRY_DELAY_MS = 1000;
const RETRY_ON_HTTP_STATUS_CODES = [503];

// This function fetches an API response and returns the corresponding json
export default function callApi({
Expand All @@ -16,6 +21,12 @@ export default function callApi({
stringify = true,
url,
}: CallApi): Promise<Response> {
const fetchWithRetry = fetchRetry(fetch, {
retries: RETRY_COUNT,
retryDelay: RETRY_DELAY_MS,
retryOn: RETRY_ON_HTTP_STATUS_CODES,
});

const request = {
body,
cache,
Expand Down Expand Up @@ -43,7 +54,7 @@ export default function callApi({
request.headers = { ...request.headers, 'If-None-Match': etag };
}

return fetch(url, request);
return fetchWithRetry(url, request);
})
.then(response => {
if (response.status === HTTP_STATUS_NOT_MODIFIED) {
Expand Down Expand Up @@ -82,5 +93,5 @@ export default function callApi({
request.body = formData;
}

return fetch(url, request);
return fetchWithRetry(url, request);
}
14 changes: 12 additions & 2 deletions packages/superset-ui-connection/test/callApi/callApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('callApi()', () => {
const mockPatchUrl = '/mock/patch/url';
const mockCacheUrl = '/mock/cache/url';
const mockNotFound = '/mock/notfound';
const mock503 = '/mock/503';

const mockGetPayload = { get: 'payload' };
const mockPostPayload = { post: 'payload' };
Expand All @@ -37,6 +38,7 @@ describe('callApi()', () => {
fetchMock.patch(mockPatchUrl, mockPatchPayload);
fetchMock.get(mockCacheUrl, mockCachePayload);
fetchMock.get(mockNotFound, { status: 404 });
fetchMock.get(mock503, { status: 503 });

afterEach(fetchMock.reset);

Expand Down Expand Up @@ -437,7 +439,7 @@ describe('callApi()', () => {
});
});

it('rejects if the request throws', () => {
it('rejects after retrying thrice if the request throws', () => {
const mockErrorUrl = '/mock/error/url';
const mockErrorPayload = { status: 500, statusText: 'Internal error' };
fetchMock.get(mockErrorUrl, () => Promise.reject(mockErrorPayload));
Expand All @@ -447,9 +449,17 @@ describe('callApi()', () => {
return callApi({ url: mockErrorUrl, method: 'GET' })
.then(throwIfCalled)
.catch(error => {
expect(fetchMock.calls(mockErrorUrl)).toHaveLength(1);
expect(fetchMock.calls(mockErrorUrl)).toHaveLength(4);
expect(error.status).toBe(mockErrorPayload.status);
expect(error.statusText).toBe(mockErrorPayload.statusText);
});
});

it('rejects after retrying thrice if the request returns a 503', async () => {
const url = mock503;
const response = await callApi({ url, method: 'GET' });
const calls = fetchMock.calls(url);
expect(calls).toHaveLength(4);
expect(response.status).toEqual(503);
});
});
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8001,7 +8001,7 @@ es5-shim@^4.5.13:
resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.14.tgz#90009e1019d0ea327447cb523deaff8fe45697ef"
integrity sha512-7SwlpL+2JpymWTt8sNLuC2zdhhc+wrfe5cMPI2j0o6WsPdfAiPwmFy2f0AocPB4RQVBOZ9kNTgi5YF7TdhkvEg==

es6-promise@^4.0.3:
es6-promise@^4.0.3, es6-promise@^4.2.8:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
Expand Down Expand Up @@ -8679,6 +8679,13 @@ fetch-mock@^7.2.5:
path-to-regexp "^2.2.1"
whatwg-url "^6.5.0"

fetch-retry@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-3.1.0.tgz#53a25652adf56def526f9b6f6d749a5bebffd319"
integrity sha512-pHCYCq7g854KkebphR3tKb4M7TJK91ZI0K2BU82cWv+vNkFQn0PZZFrQd/mL+Ra/mj2HLZNvzkTRjPEq2Dh/Bg==
dependencies:
es6-promise "^4.2.8"

figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.2"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
Expand Down

0 comments on commit 28915a2

Please sign in to comment.