Skip to content

Commit bf50ee8

Browse files
authored
Merge pull request #239 from contentstack/fix/DX-9991-timeout-error-handling
fix: classify request timeouts distinctly instead of unknown error
2 parents 606c6a5 + d911f4c commit bf50ee8

2 files changed

Lines changed: 28 additions & 15 deletions

File tree

‎src/lib/retryPolicy/delivery-sdk-handlers.ts‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable @typescript-eslint/no-throw-literal */
21
import axios, { InternalAxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
32
import { ERROR_MESSAGES } from '../error-messages';
43

@@ -59,12 +58,9 @@ export const retryResponseErrorHandler = (error: any, config: any, axiosInstance
5958
}
6059

6160
if (error.code === 'ECONNABORTED') {
62-
const customError = {
63-
error_message: ERROR_MESSAGES.RETRY.TIMEOUT_EXCEEDED(config.timeout),
64-
error_code: ERROR_MESSAGES.ERROR_CODES.TIMEOUT,
65-
errors: null,
66-
};
67-
throw customError; // Throw customError object
61+
const timeoutError = new Error(ERROR_MESSAGES.RETRY.TIMEOUT_EXCEEDED(config.timeout));
62+
(timeoutError as any).code = ERROR_MESSAGES.ERROR_CODES.TIMEOUT;
63+
throw timeoutError;
6864
}
6965

7066
throw error;

‎test/retryPolicy/delivery-sdk-handlers.spec.ts‎

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
getRetryDelay,
99
} from '../../src/lib/retryPolicy/delivery-sdk-handlers';
1010
import MockAdapter from 'axios-mock-adapter';
11+
import { APIError } from '../../src/lib/api-error';
1112

1213
describe('retryRequestHandler', () => {
1314
it('should add retryCount to the request config', () => {
@@ -201,22 +202,38 @@ describe('retryResponseErrorHandler', () => {
201202
jest.useRealTimers();
202203
});
203204

204-
it('should resolve the promise to 408 error if retryOnError is true and error code is ECONNABORTED', async () => {
205+
it('should throw a real Error with the timeout duration and a TIMEOUT code when ECONNABORTED occurs', async () => {
205206
const error = { config: { retryOnError: true, retryCount: 1 }, code: 'ECONNABORTED' };
206207
const config = { retryLimit: 5, timeout: 1000 };
207208
const client = axios.create();
208209
try {
209210
await retryResponseErrorHandler(error, config, client);
210211
fail('Expected retryResponseErrorHandler to throw an error');
211-
} catch (err) {
212-
expect(err).toEqual(
213-
expect.objectContaining({
214-
error_code: 408,
215-
error_message: `Request timeout of ${config.timeout}ms exceeded. Please try again or increase the timeout value in your configuration.`,
216-
errors: null,
217-
})
212+
} catch (err: any) {
213+
expect(err).toBeInstanceOf(Error);
214+
expect(err.message).toBe(
215+
`Request timeout of ${config.timeout}ms exceeded. Please try again or increase the timeout value in your configuration.`
218216
);
217+
expect(err.code).toBe(408);
218+
}
219+
});
220+
it('should classify a request timeout distinctly instead of as an unknown error', async () => {
221+
const error = { config: { retryOnError: true, retryCount: 1 }, code: 'ECONNABORTED' };
222+
const config = { retryLimit: 5, timeout: 1000 };
223+
const client = axios.create();
224+
225+
let thrown: any;
226+
try {
227+
await retryResponseErrorHandler(error, config, client);
228+
fail('Expected retryResponseErrorHandler to throw an error');
229+
} catch (err) {
230+
thrown = err;
219231
}
232+
233+
const apiError = APIError.fromAxiosError(thrown);
234+
235+
expect(apiError.error_code).toBe(408);
236+
expect(apiError.error_message).toContain('timeout');
220237
});
221238
it('should reject the promise if response status is 429 and retryCount exceeds retryLimit', async () => {
222239
const error = {

0 commit comments

Comments
 (0)