From 3018acbe397cd8ed922fcd508c6965fc3a540000 Mon Sep 17 00:00:00 2001 From: Gil Pedersen Date: Mon, 4 Aug 2025 14:19:19 +0200 Subject: [PATCH 1/2] Fix late write error on aborted streams --- lib/index.js | 2 +- test/index.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index 0749432..41fa1b3 100755 --- a/lib/index.js +++ b/lib/index.js @@ -332,7 +332,7 @@ internals.writeFile = function (req, options, stream) { unpipeStreamToCounter(); unpipeCounterToFile(); - file.destroy(); + file.close(); Fs.unlink(path, (/* fsErr */) => reject(err)); // Ignore unlink errors return; } diff --git a/test/index.js b/test/index.js index 2faae48..0e8ce4f 100755 --- a/test/index.js +++ b/test/index.js @@ -1286,7 +1286,7 @@ describe('parse()', () => { expect(fileContents.toString('binary') === buffer.toString('binary')).to.equal(true); }); - it('cleans file when stream is aborted', { retry: true }, async () => { + it('cleans file when stream is aborted', async () => { const path = Path.join(__dirname, 'file'); const count = Fs.readdirSync(path).length; @@ -1304,13 +1304,13 @@ describe('parse()', () => { }; const req = Http.request(options, (res) => { }); - req.on('error', Hoek.ignore); + req.on('error', Hoek.ignore); // For some reason the stream errors _after_ being destroyed... const random = Buffer.alloc(100000); req.write(random); req.write(random); await Hoek.wait(500); - req.abort(); + req.destroy(); const incoming = await receive; await expect(Subtext.parse(incoming, null, { parse: false, output: 'file', uploads: path })).to.reject(/Client connection aborted/); From a7815d814a1333de30950247db4bfe0d43f03da4 Mon Sep 17 00:00:00 2001 From: Gil Pedersen Date: Tue, 5 Aug 2025 16:56:21 +0200 Subject: [PATCH 2/2] Cleanup unexpected error test --- test/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/index.js b/test/index.js index 0e8ce4f..505d964 100755 --- a/test/index.js +++ b/test/index.js @@ -1304,7 +1304,6 @@ describe('parse()', () => { }; const req = Http.request(options, (res) => { }); - req.on('error', Hoek.ignore); // For some reason the stream errors _after_ being destroyed... const random = Buffer.alloc(100000); req.write(random); req.write(random); @@ -1312,8 +1311,18 @@ describe('parse()', () => { await Hoek.wait(500); req.destroy(); + let error; + req.once('error', (err) => (error = err)); + const incoming = await receive; await expect(Subtext.parse(incoming, null, { parse: false, output: 'file', uploads: path })).to.reject(/Client connection aborted/); + + if (error) { + // For some reason the stream can error _after_ being destroyed... + + expect(error).to.contain({ code: 'ECONNRESET' }).and.be.an.error(); + } + expect(Fs.readdirSync(path).length).to.equal(count); });