diff --git a/package.json b/package.json index d3b37075..de124b84 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test:functional": "dotenv -e .env -- jest --projects ./test --runInBand", "test:unit": "dotenv -e .env -- jest", "style:check": "prettier --check src/**/*.ts test/**/*.ts", - "style:fix": "prettier --write src/**/*.ts' test/**/*.ts" + "style:fix": "prettier --write src/**/*.ts test/**/*.ts" }, "engines": { "node": "14" diff --git a/src/clients/__test__/stormGlass.test.ts b/src/clients/__test__/stormGlass.test.ts index 959e629a..346b6271 100644 --- a/src/clients/__test__/stormGlass.test.ts +++ b/src/clients/__test__/stormGlass.test.ts @@ -78,14 +78,14 @@ describe('StormGlass client', () => { const lat = -33.792726; const lng = 151.289824; - mockedRequest.get.mockRejectedValue({ message: 'Network Error' }); + mockedRequest.get.mockRejectedValue('Network Error'); MockedCacheUtil.get.mockReturnValue(undefined); const stormGlass = new StormGlass(mockedRequest, MockedCacheUtil); await expect(stormGlass.fetchPoints(lat, lng)).rejects.toThrow( - 'Unexpected error when trying to communicate to StormGlass: Network Error' + 'Unexpected error when trying to communicate to StormGlass: "Network Error"' ); }); @@ -93,16 +93,26 @@ describe('StormGlass client', () => { const lat = -33.792726; const lng = 151.289824; - mockedRequest.get.mockRejectedValue({ - response: { + class FakeAxiosError extends Error { + constructor(public response: object) { + super(); + } + } + + mockedRequest.get.mockRejectedValue( + new FakeAxiosError({ status: 429, data: { errors: ['Rate Limit reached'] }, - }, - }); + }) + ); /** * Mock static function return */ MockedRequestClass.isRequestError.mockReturnValue(true); + MockedRequestClass.extractErrorData.mockReturnValue({ + status: 429, + data: { errors: ['Rate Limit reached'] }, + }); MockedCacheUtil.get.mockReturnValue(undefined); diff --git a/src/clients/stormGlass.ts b/src/clients/stormGlass.ts index 1629d225..6e4d8db9 100644 --- a/src/clients/stormGlass.ts +++ b/src/clients/stormGlass.ts @@ -115,18 +115,17 @@ export class StormGlass { } ); return this.normalizeResponse(response.data); - } catch (err) { - /** - * This is handling the Axios errors specifically - */ - if (HTTPUtil.Request.isRequestError(err)) { + } catch (err: unknown) { + if (err instanceof Error && HTTPUtil.Request.isRequestError(err)) { + const error = HTTPUtil.Request.extractErrorData(err); throw new StormGlassResponseError( - `Error: ${JSON.stringify(err.response.data)} Code: ${ - err.response.status - }` + `Error: ${JSON.stringify(error.data)} Code: ${error.status}` ); } - throw new ClientRequestError(err.message); + /** + * All the other errors will fallback to a generic client error + */ + throw new ClientRequestError(JSON.stringify(err)); } } diff --git a/src/util/request.ts b/src/util/request.ts index 20a1c357..dabb2528 100644 --- a/src/util/request.ts +++ b/src/util/request.ts @@ -12,7 +12,22 @@ export class Request { return this.request.get>(url, config); } - public static isRequestError(error: AxiosError): boolean { - return !!(error.response && error.response.status); + public static isRequestError(error: Error): boolean { + return !!( + (error as AxiosError).response && (error as AxiosError).response?.status + ); + } + + public static extractErrorData( + error: unknown + ): Pick { + const axiosError = error as AxiosError; + if (axiosError.response && axiosError.response.status) { + return { + data: axiosError.response.data, + status: axiosError.response.status, + }; + } + throw Error(`The error ${error} is not a Request Error`); } }