diff --git a/src/retry.ts b/src/retry.ts index b9e94b43..5e3f608b 100644 --- a/src/retry.ts +++ b/src/retry.ts @@ -89,6 +89,12 @@ export async function getRetryConfig(err: GaxiosError) { function shouldRetryRequest(err: GaxiosError) { const config = getConfig(err); + // node-fetch raises an AbortError if signaled: + // https://github.com/bitinn/node-fetch#request-cancellation-with-abortsignal + if (err.name === 'AbortError') { + return false; + } + // If there's no config, or retries are disabled, return. if (!config || config.retry === 0) { return false; diff --git a/test/test.retry.ts b/test/test.retry.ts index 93d5c3ff..6813001f 100644 --- a/test/test.retry.ts +++ b/test/test.retry.ts @@ -14,6 +14,7 @@ import assert from 'assert'; import nock from 'nock'; +import {AbortController} from 'abort-controller'; import {GaxiosError, GaxiosOptions, request, Gaxios} from '../src'; const assertRejects = require('assert-rejects'); @@ -102,6 +103,25 @@ describe('🛸 retry & exponential backoff', () => { scope.done(); }); + it('should not retry if user aborted request', async () => { + const ac = new AbortController(); + const config: GaxiosOptions = { + method: 'GET', + url: 'https://google.com', + signal: ac.signal, + retryConfig: {retry: 10, noResponseRetries: 10}, + }; + const req = request(config); + ac.abort(); + try { + await req; + throw Error('unreachable'); + } catch (err) { + assert(err.config); + assert.strictEqual(err.config.retryConfig.currentRetryAttempt, 0); + } + }); + it('should retry at least the configured number of times', async () => { const body = {dippy: '🥚'}; const scopes = [