From 8e025d1cf5a453ff158cb1bd40ff6929e1b27bb1 Mon Sep 17 00:00:00 2001 From: Carlos Fuentes Date: Wed, 16 Oct 2024 20:23:47 +0200 Subject: [PATCH] fix(#3736): leaked error event on response body (#3740) --- lib/api/api-request.js | 2 +- test/client-request.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/api/api-request.js b/lib/api/api-request.js index 2c86dd07c58..1bf07b392aa 100644 --- a/lib/api/api-request.js +++ b/lib/api/api-request.js @@ -65,7 +65,7 @@ class RequestHandler extends AsyncResource { this.removeAbortListener = util.addAbortListener(signal, () => { this.reason = signal.reason ?? new RequestAbortedError() if (this.res) { - util.destroy(this.res, this.reason) + util.destroy(this.res.on('error', noop), this.reason) } else if (this.abort) { this.abort(this.reason) } diff --git a/test/client-request.js b/test/client-request.js index 27555d5186a..9712820b3a3 100644 --- a/test/client-request.js +++ b/test/client-request.js @@ -1337,3 +1337,39 @@ test('request multibyte text with setEncoding', async (t) => { await t.completed }) + +test('#3736 - Aborted Response (without consuming body)', async (t) => { + const plan = tspl(t, { plan: 1 }) + + const controller = new AbortController() + const server = createServer((req, res) => { + setTimeout(() => { + res.writeHead(200, 'ok', { + 'content-type': 'text/plain' + }) + res.write('hello from server') + res.end() + }, 100) + }) + + server.listen(0) + + await EE.once(server, 'listening') + const client = new Client(`http://localhost:${server.address().port}`) + + after(server.close.bind(server)) + after(client.destroy.bind(client)) + + const { signal } = controller + const promise = client.request({ + path: '/', + method: 'GET', + signal + }) + + controller.abort() + + await plan.rejects(promise, { message: 'This operation was aborted' }) + + await plan.completed +})