diff --git a/lib/fetch/index.js b/lib/fetch/index.js index 7388da51ffc..f69371a941d 100644 --- a/lib/fetch/index.js +++ b/lib/fetch/index.js @@ -180,14 +180,15 @@ async function fetch (input, init = {}) { // 1. Set locallyAborted to true. locallyAborted = true - // 2. Abort the fetch() call with p, request, responseObject, + // 2. Assert: controller is non-null. + assert(controller != null) + + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason) + + // 4. Abort the fetch() call with p, request, responseObject, // and requestObject’s signal’s abort reason. abortFetch(p, request, responseObject, requestObject.signal.reason) - - // 3. If controller is not null, then abort controller. - if (controller != null) { - controller.abort() - } }, { once: true } ) diff --git a/test/fetch/issue-2171.js b/test/fetch/issue-2171.js new file mode 100644 index 00000000000..b04ae0e6c38 --- /dev/null +++ b/test/fetch/issue-2171.js @@ -0,0 +1,25 @@ +'use strict' + +const { fetch } = require('../..') +const { DOMException } = require('../../lib/fetch/constants') +const { once } = require('events') +const { createServer } = require('http') +const { test } = require('tap') + +test('error reason is forwarded - issue #2171', { skip: !AbortSignal.timeout }, async (t) => { + const server = createServer(() => {}).listen(0) + + t.teardown(server.close.bind(server)) + await once(server, 'listening') + + const timeout = AbortSignal.timeout(100) + await t.rejects( + fetch(`http://localhost:${server.address().port}`, { + signal: timeout + }), + { + name: 'TimeoutError', + code: DOMException.TIMEOUT_ERR + } + ) +})