diff --git a/source/core/Ky.ts b/source/core/Ky.ts index bef52b79..62e3d977 100644 --- a/source/core/Ky.ts +++ b/source/core/Ky.ts @@ -208,7 +208,7 @@ export class Ky { protected _calculateRetryDelay(error: unknown) { this._retryCount++; - if (this._retryCount < this._options.retry.limit && !(error instanceof TimeoutError)) { + if (this._retryCount <= this._options.retry.limit && !(error instanceof TimeoutError)) { if (error instanceof HTTPError) { if (!this._options.retry.statusCodes.includes(error.response.status)) { return 0; diff --git a/test/browser.ts b/test/browser.ts index 537f83a6..e8766dcf 100644 --- a/test/browser.ts +++ b/test/browser.ts @@ -480,7 +480,7 @@ browserTest('retry with body', [chromium, webkit], async (t: ExecutionContext, p page.evaluate(async (url: string) => window.ky(`${url}/test`, { body: 'foo', method: 'PUT', - retry: 2, + retry: 1, }), server.url), {message: /HTTPError: Request failed with status code 502 Bad Gateway/}, ); diff --git a/test/hooks.ts b/test/hooks.ts index 6b40012f..190dd0b6 100644 --- a/test/hooks.ts +++ b/test/hooks.ts @@ -427,7 +427,7 @@ test('beforeRetry hook is called even if the error has no response', async t => const text = await ky .get(server.url, { - retry: 2, + retry: 1, async fetch(request) { if (requestCount === 0) { requestCount++; @@ -473,7 +473,7 @@ test('beforeRetry hook with parseJson and error.response.json()', async t => { const json = await ky .get(server.url, { - retry: 2, + retry: 1, parseJson(text) { t.is(text, 'text'); return {awesome: true}; diff --git a/test/retry.ts b/test/retry.ts index 5826c146..3f45c65e 100644 --- a/test/retry.ts +++ b/test/retry.ts @@ -15,7 +15,7 @@ test('network error', async t => { server.get('/', (_request, response) => { requestCount++; - if (requestCount === defaultRetryCount) { + if (requestCount === defaultRetryCount + 1) { response.end(fixture); } else { response.status(99_999).end(); @@ -34,7 +34,7 @@ test('status code 500', async t => { server.get('/', (_request, response) => { requestCount++; - if (requestCount === defaultRetryCount) { + if (requestCount === defaultRetryCount + 1) { response.end(fixture); } else { response.sendStatus(500); @@ -53,7 +53,7 @@ test('only on defined status codes', async t => { server.get('/', (_request, response) => { requestCount++; - if (requestCount === defaultRetryCount) { + if (requestCount === defaultRetryCount + 1) { response.end(fixture); } else { response.sendStatus(400); @@ -72,7 +72,7 @@ test('not on POST', async t => { server.post('/', (_request, response) => { requestCount++; - if (requestCount === defaultRetryCount) { + if (requestCount === defaultRetryCount + 1) { response.end(fixture); } else { response.sendStatus(500); @@ -93,7 +93,7 @@ test('respect 413 Retry-After', async t => { server.get('/', (_request, response) => { requestCount++; - if (requestCount === defaultRetryCount) { + if (requestCount === defaultRetryCount + 1) { response.end((Date.now() - lastTried413access).toString()); } else { response.writeHead(413, { @@ -115,7 +115,7 @@ test('respect 413 Retry-After with timestamp', async t => { const server = await createHttpTestServer({bodyParser: false}); server.get('/', (_request, response) => { requestCount++; - if (requestCount === defaultRetryCount) { + if (requestCount === defaultRetryCount + 1) { response.end((Date.now() - lastTried413access).toString()); } else { // @NOTE we need to round up to the next second due to http-date resolution @@ -129,7 +129,7 @@ test('respect 413 Retry-After with timestamp', async t => { const result = await ky(server.url).text(); t.true(Number(result) >= retryAfterOn413 * 1000); - t.is(requestCount, 2); + t.is(requestCount, 3); await server.close(); }); @@ -151,7 +151,7 @@ test('doesn\'t retry on 413 without Retry-After header', async t => { await server.close(); }); -test.failing('respect number of retries', async t => { +test('respect number of retries', async t => { let requestCount = 0; const server = await createHttpTestServer(); @@ -207,7 +207,7 @@ test('respect retry methods', async t => { await t.throwsAsync( ky(server.url, { retry: { - limit: 3, + limit: 2, methods: ['get'], }, }).text(), @@ -251,7 +251,7 @@ test('respect maxRetryAfter', async t => { await t.throwsAsync( ky(server.url, { retry: { - limit: 5, + limit: 4, maxRetryAfter: 2000, }, }).text(), @@ -273,7 +273,7 @@ test('retry - can provide retry as number', async t => { response.sendStatus(408); }); - await t.throwsAsync(ky(server.url, {retry: 5}).text(), { + await t.throwsAsync(ky(server.url, {retry: 4}).text(), { message: /Request Timeout/, }); t.is(requestCount, 5); @@ -347,7 +347,7 @@ test('does retry on 408 with methods provided as array', async t => { await t.throwsAsync( ky(server.url, { retry: { - limit: 4, + limit: 3, methods: ['get'], }, }).text(), @@ -373,7 +373,7 @@ test('does retry on 408 with statusCodes provided as array', async t => { await t.throwsAsync( ky(server.url, { retry: { - limit: 4, + limit: 3, statusCodes: [408], }, }).text(), @@ -443,14 +443,14 @@ test('throws when retry.statusCodes is not an array', async t => { }); test('respect maximum backoff', async t => { - const retryCount = 5; + const retryCount = 4; let requestCount = 0; const server = await createHttpTestServer(); server.get('/', (_request, response) => { requestCount++; - if (requestCount === retryCount) { + if (requestCount === retryCount + 1) { response.end(fixture); } else { response.sendStatus(500);