Skip to content

Commit 47f9b96

Browse files
authored
fix: set finalizer only for fetch responses (#4803)
1 parent 92e38fc commit 47f9b96

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/web/fetch/response.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ class Response {
242242
const clonedResponse = cloneResponse(this.#state)
243243

244244
// Note: To re-register because of a new stream.
245-
if (this.#state.body?.stream) {
245+
// Don't set finalizers other than for fetch responses.
246+
if (this.#state.urlList.length !== 0 && this.#state.body?.stream) {
246247
streamRegistry.register(this, new WeakRef(this.#state.body.stream))
247248
}
248249

test/fetch/fire-and-forget.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,42 @@ test('test finalizer cloned response', async () => {
4646
await response.arrayBuffer() // check consume body
4747
})
4848

49+
// https://github.com/nodejs/undici/pull/4803
50+
test('should not call cancel() during GC (new Response)', async () => {
51+
if (!hasGC) {
52+
throw new Error('gc is not available. Run with \'--expose-gc\'.')
53+
}
54+
55+
let response = new Response(new ReadableStream({
56+
start () {},
57+
58+
pull (ctrl) {
59+
ctrl.enqueue(new Uint8Array([72, 101, 108, 108, 111])) // Hello
60+
},
61+
62+
cancel () {
63+
throw new Error('should be unreachable')
64+
}
65+
}))
66+
67+
let cloned = response.clone()
68+
69+
const body = response.body
70+
71+
await nextTick()
72+
cloned.body.cancel()
73+
74+
cloned = null
75+
response = null
76+
77+
await nextTick()
78+
// eslint-disable-next-line no-undef
79+
gc()
80+
81+
await nextTick(); // handle 'uncaughtException' event
82+
(function () {})(body) // save a reference without triggering linter warnings
83+
})
84+
4985
test('does not need the body to be consumed to continue', { timeout: 180_000 }, async (t) => {
5086
if (!hasGC) {
5187
throw new Error('gc is not available. Run with \'--expose-gc\'.')

0 commit comments

Comments
 (0)