@internetarchive/fetch-handler 1.1.0-webdev-7731.5 → 1.1.0-webdev-7731.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/fetch-retry/configuration/default-retry-configuration.d.ts +2 -1
- package/dist/src/fetch-retry/configuration/default-retry-configuration.js +11 -4
- package/dist/src/fetch-retry/configuration/default-retry-configuration.js.map +1 -1
- package/dist/test/default-retry-config.test.js +16 -11
- package/dist/test/default-retry-config.test.js.map +1 -1
- package/package.json +1 -1
- package/src/fetch-retry/configuration/default-retry-configuration.ts +15 -5
- package/test/default-retry-config.test.ts +17 -12
|
@@ -5,8 +5,9 @@ export declare class DefaultRetryConfiguration implements RetryConfiguring {
|
|
|
5
5
|
private readonly maxRetries;
|
|
6
6
|
constructor(options?: {
|
|
7
7
|
maxRetries?: number;
|
|
8
|
+
transientStatusCodes?: Set<number>;
|
|
8
9
|
});
|
|
9
|
-
|
|
10
|
+
readonly transientStatusCodes: ReadonlySet<number>;
|
|
10
11
|
shouldRetry(response: Response | null, retryNumber: number): boolean;
|
|
11
12
|
retryDelay(retryNumber: number, response?: Response | null): Milliseconds;
|
|
12
13
|
}
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
export class DefaultRetryConfiguration {
|
|
2
2
|
constructor(options) {
|
|
3
3
|
this.maxRetries = 2;
|
|
4
|
-
this.
|
|
4
|
+
this.transientStatusCodes = new Set([
|
|
5
5
|
408, // Request Timeout
|
|
6
6
|
429, // Too Many Requests
|
|
7
|
+
500, // Internal Server Error
|
|
8
|
+
502, // Bad Gateway
|
|
9
|
+
503, // Service Unavailable
|
|
10
|
+
504, // Gateway Timeout
|
|
11
|
+
522, // Cloudflare Origin Server Connection Timed Out
|
|
7
12
|
]);
|
|
8
13
|
if ((options === null || options === void 0 ? void 0 : options.maxRetries) !== undefined) {
|
|
9
14
|
this.maxRetries = options.maxRetries;
|
|
10
15
|
}
|
|
16
|
+
if ((options === null || options === void 0 ? void 0 : options.transientStatusCodes) !== undefined) {
|
|
17
|
+
this.transientStatusCodes = options.transientStatusCodes;
|
|
18
|
+
}
|
|
11
19
|
}
|
|
12
20
|
shouldRetry(response, retryNumber) {
|
|
13
21
|
if (response === null)
|
|
14
22
|
return false;
|
|
15
23
|
if (retryNumber > this.maxRetries)
|
|
16
24
|
return false;
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
return is5xx || isTransient4xx;
|
|
25
|
+
const isTransient = this.transientStatusCodes.has(response.status);
|
|
26
|
+
return isTransient;
|
|
20
27
|
}
|
|
21
28
|
retryDelay(retryNumber, response) {
|
|
22
29
|
// If we have a Retry-After header, use that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-retry-configuration.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/default-retry-configuration.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,yBAAyB;IAMpC,YAAY,
|
|
1
|
+
{"version":3,"file":"default-retry-configuration.js","sourceRoot":"","sources":["../../../../src/fetch-retry/configuration/default-retry-configuration.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,yBAAyB;IAMpC,YAAY,OAGX;QALgB,eAAU,GAAqB,CAAC,CAAC;QAczC,yBAAoB,GAAwB,IAAI,GAAG,CAAC;YAC3D,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,oBAAoB;YACzB,GAAG,EAAE,wBAAwB;YAC7B,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,sBAAsB;YAC3B,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,gDAAgD;SACtD,CAAC,CAAC;QAhBD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,MAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACvC,CAAC;QACD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB,MAAK,SAAS,EAAE,CAAC;YAChD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QAC3D,CAAC;IACH,CAAC;IAYD,WAAW,CAAC,QAAyB,EAAE,WAAmB;QACxD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACpC,IAAI,WAAW,GAAG,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnE,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,UAAU,CAAC,WAAmB,EAAE,QAA0B;QACxD,4CAA4C;QAC5C,MAAM,UAAU,GAAG,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACxD,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC9B,OAAO,iBAAiB,GAAG,IAAI,CAAC;YAClC,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,WAAW,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;;AA9Ce,gCAAM,GACpB,IAAI,yBAAyB,EAAE,AADX,CACY","sourcesContent":["import type { RetryConfiguring } from './retry-configuring';\nimport type { Milliseconds } from './milliseconds';\n\nexport class DefaultRetryConfiguration implements RetryConfiguring {\n static readonly shared: Readonly<RetryConfiguring> =\n new DefaultRetryConfiguration();\n\n private readonly maxRetries: Readonly<number> = 2;\n\n constructor(options?: {\n maxRetries?: number;\n transientStatusCodes?: Set<number>;\n }) {\n if (options?.maxRetries !== undefined) {\n this.maxRetries = options.maxRetries;\n }\n if (options?.transientStatusCodes !== undefined) {\n this.transientStatusCodes = options.transientStatusCodes;\n }\n }\n\n readonly transientStatusCodes: ReadonlySet<number> = new Set([\n 408, // Request Timeout\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n 522, // Cloudflare Origin Server Connection Timed Out\n ]);\n\n shouldRetry(response: Response | null, retryNumber: number): boolean {\n if (response === null) return false;\n if (retryNumber > this.maxRetries) return false;\n const isTransient = this.transientStatusCodes.has(response.status);\n return isTransient;\n }\n\n retryDelay(retryNumber: number, response?: Response | null): Milliseconds {\n // If we have a Retry-After header, use that\n const retryAfter = response?.headers.get('Retry-After');\n if (retryAfter) {\n const retryAfterSeconds = parseInt(retryAfter, 10);\n if (!isNaN(retryAfterSeconds)) {\n return retryAfterSeconds * 1000;\n }\n }\n\n // Exponential backoff up to 10 seconds\n return Math.min(500 * 2 ** retryNumber, 10000);\n }\n}\n"]}
|
|
@@ -10,22 +10,21 @@ describe('DefaultRetryConfiguration', () => {
|
|
|
10
10
|
const mockResponse = new Response(null, { status: 500 });
|
|
11
11
|
expect(config.shouldRetry(mockResponse, 3)).to.be.false;
|
|
12
12
|
});
|
|
13
|
-
it('should retry
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
13
|
+
it('should retry transient status codes', async () => {
|
|
14
|
+
const transientStatuses = [408, 429, 500, 502, 503, 504];
|
|
15
|
+
const config = new DefaultRetryConfiguration({
|
|
16
|
+
transientStatusCodes: new Set(transientStatuses),
|
|
17
|
+
});
|
|
18
|
+
for (const status of transientStatuses) {
|
|
19
|
+
const mockResponse = new Response(null, { status });
|
|
20
|
+
expect(config.shouldRetry(mockResponse, 1)).to.be.true;
|
|
21
|
+
}
|
|
17
22
|
});
|
|
18
|
-
it('should not retry
|
|
23
|
+
it('should not retry non-transient status codes', async () => {
|
|
19
24
|
const config = new DefaultRetryConfiguration();
|
|
20
25
|
const mockResponse = new Response(null, { status: 404 });
|
|
21
26
|
expect(config.shouldRetry(mockResponse, 1)).to.be.false;
|
|
22
27
|
});
|
|
23
|
-
it('has exponential backoff delay', async () => {
|
|
24
|
-
const config = new DefaultRetryConfiguration();
|
|
25
|
-
expect(config.retryDelay(0)).to.equal(500);
|
|
26
|
-
expect(config.retryDelay(1)).to.equal(1000);
|
|
27
|
-
expect(config.retryDelay(2)).to.equal(2000);
|
|
28
|
-
});
|
|
29
28
|
it('uses Retry-After header if present', async () => {
|
|
30
29
|
const config = new DefaultRetryConfiguration();
|
|
31
30
|
const headers = new Headers();
|
|
@@ -33,6 +32,12 @@ describe('DefaultRetryConfiguration', () => {
|
|
|
33
32
|
const mockResponse = new Response(null, { status: 503, headers });
|
|
34
33
|
expect(config.retryDelay(0, mockResponse)).to.equal(3000);
|
|
35
34
|
});
|
|
35
|
+
it('has exponential backoff delay', async () => {
|
|
36
|
+
const config = new DefaultRetryConfiguration();
|
|
37
|
+
expect(config.retryDelay(0)).to.equal(500);
|
|
38
|
+
expect(config.retryDelay(1)).to.equal(1000);
|
|
39
|
+
expect(config.retryDelay(2)).to.equal(2000);
|
|
40
|
+
});
|
|
36
41
|
it('caps retry delay at 10 seconds', async () => {
|
|
37
42
|
const config = new DefaultRetryConfiguration();
|
|
38
43
|
expect(config.retryDelay(10)).to.equal(10000);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-retry-config.test.js","sourceRoot":"","sources":["../../test/default-retry-config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,8DAA8D,CAAC;AAEzG,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,MAAM,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAI,yBAAyB,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAChE,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"default-retry-config.test.js","sourceRoot":"","sources":["../../test/default-retry-config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,yBAAyB,EAAE,MAAM,8DAA8D,CAAC;AAEzG,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,MAAM,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAI,yBAAyB,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAChE,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,yBAAyB,CAAC;YAC3C,oBAAoB,EAAE,IAAI,GAAG,CAAC,iBAAiB,CAAC;SACjD,CAAC,CAAC;QACH,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;YACvC,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YACpD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC/C,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACnC,MAAM,YAAY,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,MAAM,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,MAAM,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { DefaultRetryConfiguration } from '../src/fetch-retry/configuration/default-retry-configuration';\n\ndescribe('DefaultRetryConfiguration', () => {\n it('should not retry on null response', async () => {\n const config = new DefaultRetryConfiguration();\n expect(config.shouldRetry(null, 1)).to.be.false;\n });\n\n it('should not retry after max retries exceeded', async () => {\n const config = new DefaultRetryConfiguration({ maxRetries: 2 });\n const mockResponse = new Response(null, { status: 500 });\n expect(config.shouldRetry(mockResponse, 3)).to.be.false;\n });\n\n it('should retry transient status codes', async () => {\n const transientStatuses = [408, 429, 500, 502, 503, 504];\n const config = new DefaultRetryConfiguration({\n transientStatusCodes: new Set(transientStatuses),\n });\n for (const status of transientStatuses) {\n const mockResponse = new Response(null, { status });\n expect(config.shouldRetry(mockResponse, 1)).to.be.true;\n }\n });\n\n it('should not retry non-transient status codes', async () => {\n const config = new DefaultRetryConfiguration();\n const mockResponse = new Response(null, { status: 404 });\n expect(config.shouldRetry(mockResponse, 1)).to.be.false;\n });\n\n it('uses Retry-After header if present', async () => {\n const config = new DefaultRetryConfiguration();\n const headers = new Headers();\n headers.append('Retry-After', '3');\n const mockResponse = new Response(null, { status: 503, headers });\n expect(config.retryDelay(0, mockResponse)).to.equal(3000);\n });\n\n it('has exponential backoff delay', async () => {\n const config = new DefaultRetryConfiguration();\n expect(config.retryDelay(0)).to.equal(500);\n expect(config.retryDelay(1)).to.equal(1000);\n expect(config.retryDelay(2)).to.equal(2000);\n });\n\n it('caps retry delay at 10 seconds', async () => {\n const config = new DefaultRetryConfiguration();\n expect(config.retryDelay(10)).to.equal(10000);\n expect(config.retryDelay(20)).to.equal(10000);\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -7,23 +7,33 @@ export class DefaultRetryConfiguration implements RetryConfiguring {
|
|
|
7
7
|
|
|
8
8
|
private readonly maxRetries: Readonly<number> = 2;
|
|
9
9
|
|
|
10
|
-
constructor(options?: {
|
|
10
|
+
constructor(options?: {
|
|
11
|
+
maxRetries?: number;
|
|
12
|
+
transientStatusCodes?: Set<number>;
|
|
13
|
+
}) {
|
|
11
14
|
if (options?.maxRetries !== undefined) {
|
|
12
15
|
this.maxRetries = options.maxRetries;
|
|
13
16
|
}
|
|
17
|
+
if (options?.transientStatusCodes !== undefined) {
|
|
18
|
+
this.transientStatusCodes = options.transientStatusCodes;
|
|
19
|
+
}
|
|
14
20
|
}
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
readonly transientStatusCodes: ReadonlySet<number> = new Set([
|
|
17
23
|
408, // Request Timeout
|
|
18
24
|
429, // Too Many Requests
|
|
25
|
+
500, // Internal Server Error
|
|
26
|
+
502, // Bad Gateway
|
|
27
|
+
503, // Service Unavailable
|
|
28
|
+
504, // Gateway Timeout
|
|
29
|
+
522, // Cloudflare Origin Server Connection Timed Out
|
|
19
30
|
]);
|
|
20
31
|
|
|
21
32
|
shouldRetry(response: Response | null, retryNumber: number): boolean {
|
|
22
33
|
if (response === null) return false;
|
|
23
34
|
if (retryNumber > this.maxRetries) return false;
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
return is5xx || isTransient4xx;
|
|
35
|
+
const isTransient = this.transientStatusCodes.has(response.status);
|
|
36
|
+
return isTransient;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
retryDelay(retryNumber: number, response?: Response | null): Milliseconds {
|
|
@@ -13,25 +13,23 @@ describe('DefaultRetryConfiguration', () => {
|
|
|
13
13
|
expect(config.shouldRetry(mockResponse, 3)).to.be.false;
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
it('should retry
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
16
|
+
it('should retry transient status codes', async () => {
|
|
17
|
+
const transientStatuses = [408, 429, 500, 502, 503, 504];
|
|
18
|
+
const config = new DefaultRetryConfiguration({
|
|
19
|
+
transientStatusCodes: new Set(transientStatuses),
|
|
20
|
+
});
|
|
21
|
+
for (const status of transientStatuses) {
|
|
22
|
+
const mockResponse = new Response(null, { status });
|
|
23
|
+
expect(config.shouldRetry(mockResponse, 1)).to.be.true;
|
|
24
|
+
}
|
|
20
25
|
});
|
|
21
26
|
|
|
22
|
-
it('should not retry
|
|
27
|
+
it('should not retry non-transient status codes', async () => {
|
|
23
28
|
const config = new DefaultRetryConfiguration();
|
|
24
29
|
const mockResponse = new Response(null, { status: 404 });
|
|
25
30
|
expect(config.shouldRetry(mockResponse, 1)).to.be.false;
|
|
26
31
|
});
|
|
27
32
|
|
|
28
|
-
it('has exponential backoff delay', async () => {
|
|
29
|
-
const config = new DefaultRetryConfiguration();
|
|
30
|
-
expect(config.retryDelay(0)).to.equal(500);
|
|
31
|
-
expect(config.retryDelay(1)).to.equal(1000);
|
|
32
|
-
expect(config.retryDelay(2)).to.equal(2000);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
33
|
it('uses Retry-After header if present', async () => {
|
|
36
34
|
const config = new DefaultRetryConfiguration();
|
|
37
35
|
const headers = new Headers();
|
|
@@ -40,6 +38,13 @@ describe('DefaultRetryConfiguration', () => {
|
|
|
40
38
|
expect(config.retryDelay(0, mockResponse)).to.equal(3000);
|
|
41
39
|
});
|
|
42
40
|
|
|
41
|
+
it('has exponential backoff delay', async () => {
|
|
42
|
+
const config = new DefaultRetryConfiguration();
|
|
43
|
+
expect(config.retryDelay(0)).to.equal(500);
|
|
44
|
+
expect(config.retryDelay(1)).to.equal(1000);
|
|
45
|
+
expect(config.retryDelay(2)).to.equal(2000);
|
|
46
|
+
});
|
|
47
|
+
|
|
43
48
|
it('caps retry delay at 10 seconds', async () => {
|
|
44
49
|
const config = new DefaultRetryConfiguration();
|
|
45
50
|
expect(config.retryDelay(10)).to.equal(10000);
|