diff --git a/src/constants/lib.js b/src/constants/lib.js index 2528713..c8e55f9 100644 --- a/src/constants/lib.js +++ b/src/constants/lib.js @@ -9,3 +9,5 @@ export const LIB_VERSION = '1.1.1'; export const PERSISTENCE_NAME = 'gotit.analytics.platform'; export const DISABLE_ERROR_CODE = 40101; + +export const MAXIMUM_RETRY_TIME = 5; diff --git a/src/utils/__tests__/request.test.js b/src/utils/__tests__/request.test.js index 0dee6f9..73731d9 100644 --- a/src/utils/__tests__/request.test.js +++ b/src/utils/__tests__/request.test.js @@ -1,4 +1,5 @@ import RequestHelper from '../request'; +import { MAXIMUM_RETRY_TIME } from '../../constants/lib'; describe('utils/request', () => { let instance; @@ -28,11 +29,47 @@ describe('utils/request', () => { let res = await instance.get(); expect(res).toEqual({ retry: false, data: response }); - fetch.mockRejectedValue(response); - try { - res = await instance.get(); - } catch (e) { - expect(e).toEqual({ retry: false, data: response }); - } + fetch.mockReject( + new Error({ + status: 500, + }), + ); + res = await instance.get(); + expect(res).toEqual({ retry: true, data: undefined }); + }); + + it('should handle maximum retry times for consecutive failed requests', async () => { + // Mock first request to be success to reset retry time counter + fetch.mockResponse(JSON.stringify(response)); + const successResponse = await instance.get(); + expect(successResponse).toEqual({ retry: false, data: response }); + + const requestArr = new Array(MAXIMUM_RETRY_TIME - 1).fill(); + + // Next four requests are failed, able to retry + const results = await Promise.all( + requestArr.map(async () => { + fetch.mockReject( + new Error({ + status: 500, + }), + ); + const res = await instance.get(); + return res; + }), + ); + + results.forEach((result) => { + expect(result).toEqual({ retry: true, data: undefined }); + }); + + // Fifth request is failed, should not retry + fetch.mockReject( + new Error({ + status: 500, + }), + ); + const res = await instance.get(); + expect(res).toEqual({ retry: false, data: undefined }); }); }); diff --git a/src/utils/request.js b/src/utils/request.js index fef6503..6ed685d 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -1,5 +1,8 @@ import CaseConverter from './caseConverter'; import { isEmpty } from './object'; +import { MAXIMUM_RETRY_TIME } from '../constants/lib'; + +let retryTime = 0; const defaultHeaders = { Accept: 'application/json', @@ -33,8 +36,16 @@ const request = async ( ? JSON.stringify(CaseConverter.camelCaseToSnakeCase(body)) : undefined, }); + retryTime = 0; } catch (e) { - // pass + retryTime++; + if (retryTime >= MAXIMUM_RETRY_TIME) { + retryTime = 0; + return { + retry: false, + data: undefined, + }; + } } if (!res || !res.status || res.status > 499) {