Skip to content

Commit

Permalink
Merge pull request #284 from obscurecat64/fix/last-request-time-not-w…
Browse files Browse the repository at this point in the history
…orking-correctly

Fix lastRequestTime being always the original request time
  • Loading branch information
mindhells authored Jul 22, 2024
2 parents 603b73c + 122b9a1 commit e812ab2
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
58 changes: 57 additions & 1 deletion spec/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import http from 'http';
import nock from 'nock';
import axios, { AxiosError, CanceledError, isAxiosError } from 'axios';
import axios, { AxiosError, CanceledError, InternalAxiosRequestConfig, isAxiosError } from 'axios';
import axiosRetry, {
isNetworkError,
isSafeRequestError,
Expand Down Expand Up @@ -1166,3 +1166,59 @@ describe('axiosRetry interceptors', () => {
expect(client.interceptors.response.handlers[0]).toBe(null);
});
});

describe('when requests are made', () => {
it('should be that lastRequestTime is accurate', (done) => {
const client = axios.create();
setupResponses(client, [
() => nock('http://example.com').get('/test').replyWithError(NETWORK_ERROR),
() => nock('http://example.com').get('/test').replyWithError(NETWORK_ERROR),
() => nock('http://example.com').get('/test').replyWithError(NETWORK_ERROR),
() => nock('http://example.com').get('/test').reply(200, 'It worked!')
]);

function getLastRequestTime(config?: InternalAxiosRequestConfig<any>) {
const lastRequestTime = config?.['axios-retry']?.lastRequestTime;

expect(lastRequestTime).toBeInstanceOf(Number);
return lastRequestTime as number;
}

const lastRequestTimes: number[] = [];
const DELAY = 500;
axiosRetry(client, {
retries: 3,
retryDelay: () => DELAY,
shouldResetTimeout: true,
onRetry(_retryCount, error, _requestConfig) {
const lastRequestTime = getLastRequestTime(error.config);
lastRequestTimes.push(lastRequestTime);
}
});

const startTime = Date.now();
client
.get('http://example.com/test')
.then((response) => {
const lastRequestTime = getLastRequestTime(response.config);
lastRequestTimes.push(lastRequestTime);

expect(lastRequestTimes.length).toBe(4);

const [a, b, c, d] = lastRequestTimes;

expect(a - startTime).toBeGreaterThanOrEqual(0);
expect(b - a).toBeGreaterThanOrEqual(DELAY);
expect(c - b).toBeGreaterThanOrEqual(DELAY);
expect(d - c).toBeGreaterThanOrEqual(DELAY);

// check to ensure that the delays are not unreasonably long
expect(b - a).toBeLessThan(DELAY * 1.5);
expect(c - b).toBeLessThan(DELAY * 1.5);
expect(d - c).toBeLessThan(DELAY * 1.5);

done();
})
.catch(done.fail);
});
});
9 changes: 6 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,14 @@ function getRequestOptions(

function setCurrentState(
config: AxiosRequestConfig,
defaultOptions: IAxiosRetryConfig | undefined
defaultOptions: IAxiosRetryConfig | undefined,
resetLastRequestTime = false
) {
const currentState = getRequestOptions(config, defaultOptions || {});
currentState.retryCount = currentState.retryCount || 0;
currentState.lastRequestTime = currentState.lastRequestTime || Date.now();
if (!currentState.lastRequestTime || resetLastRequestTime) {
currentState.lastRequestTime = Date.now();
}
config[namespace] = currentState;
return currentState as Required<IAxiosRetryConfigExtended>;
}
Expand Down Expand Up @@ -282,7 +285,7 @@ async function handleMaxRetryTimesExceeded(

const axiosRetry: AxiosRetry = (axiosInstance, defaultOptions) => {
const requestInterceptorId = axiosInstance.interceptors.request.use((config) => {
setCurrentState(config, defaultOptions);
setCurrentState(config, defaultOptions, true);
if (config[namespace]?.validateResponse) {
// by setting this, all HTTP responses will be go through the error interceptor first
config.validateStatus = () => false;
Expand Down

0 comments on commit e812ab2

Please sign in to comment.