Skip to content

Commit

Permalink
fix(fetch): prevent crash when fetch is aborted with null as the …
Browse files Browse the repository at this point in the history
…`AbortSignal's` `reason`
  • Loading branch information
steveluscher committed Feb 24, 2024
1 parent 8db8d9d commit 5df9e00
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 17 deletions.
2 changes: 1 addition & 1 deletion index-fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const fetchImpl = require('./lib/web/fetch').fetch

module.exports.fetch = function fetch (resource, init = undefined) {
return fetchImpl(resource, init).catch((err) => {
if (typeof err === 'object') {
if (err && typeof err === 'object') {
Error.captureStackTrace(err, this)
}
throw err
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ module.exports.fetch = async function fetch (init, options = undefined) {
try {
return await fetchImpl(init, options)
} catch (err) {
if (typeof err === 'object') {
if (err && typeof err === 'object') {
Error.captureStackTrace(err, this)
}

Expand Down
60 changes: 45 additions & 15 deletions test/fetch/issue-2242.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,54 @@
'use strict'

const { test } = require('node:test')
const { beforeEach, describe, it } = require('node:test')
const assert = require('node:assert')
const { fetch } = require('../..')
const nodeFetch = require('../../index-fetch')

test('fetch with signal already aborted', async () => {
await assert.rejects(
fetch('http://localhost', {
signal: AbortSignal.abort('Already aborted')
}),
/Already aborted/
describe('Issue #2242', () => {
['Already aborted', null, false, true, 123, Symbol('Some reason')].forEach(
(reason) =>
describe(`when an already-aborted signal's reason is \`${String(
reason
)}\``, () => {
let signal
beforeEach(() => {
signal = AbortSignal.abort(reason)
})
it('rejects with that reason ', async () => {
await assert.rejects(fetch('http://localhost', { signal }), (err) => {
assert.strictEqual(err, reason)
return true
})
})
it('rejects with that reason (from index-fetch)', async () => {
await assert.rejects(
nodeFetch.fetch('http://localhost', { signal }),
(err) => {
assert.strictEqual(err, reason)
return true
}
)
})
})
)
})

test('fetch with signal already aborted (from index-fetch)', async () => {
await assert.rejects(
nodeFetch.fetch('http://localhost', {
signal: AbortSignal.abort('Already aborted')
}),
/Already aborted/
)
describe("when an already-aborted signal's reason is `undefined`", () => {
let signal
beforeEach(() => {
signal = AbortSignal.abort(undefined)
})
it('rejects with an `AbortError`', async () => {
await assert.rejects(
fetch('http://localhost', { signal }),
new DOMException('This operation was aborted', 'AbortError')
)
})
it('rejects with an `AbortError` (from index-fetch)', async () => {
await assert.rejects(
nodeFetch.fetch('http://localhost', { signal }),
new DOMException('This operation was aborted', 'AbortError')
)
})
})
})

0 comments on commit 5df9e00

Please sign in to comment.