http: fix the reverted commit which would swallow some errors - #64566
http: fix the reverted commit which would swallow some errors#64566Archkon wants to merge 1 commit into
Conversation
A transport write error can be delivered before a readable event from the same poll cycle. Writable error handling then destroys both sides of the socket before the HTTP parser can consume an already-sent response. Defer native write errors that do not carry protocol-specific details. After pending reads run, suppress the error only when the request write and response parse are both complete. Continue reporting open writes, truncated responses, user destroy errors, and TLS protocol errors. Follow-up to: nodejs#64507 Original PR Refs: nodejs#64278 Fixes: nodejs#64272 Refs:nodejs#64511 Refs: libuv/libuv#5196 Refs: nodejs#64507 (comment) Refs: nodejs#64511 (comment) Signed-off-by: Archkon <180910180+Archkon@users.noreply.github.com>
|
Review requested:
|
|
@pimterry I think you could edit my PR branch, so could you add empty commit with only sign-off-by in commit messgae and I would squash into one commit beacuse I use the some test code authored by you? |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #64566 +/- ##
==========================================
- Coverage 90.23% 90.23% -0.01%
==========================================
Files 739 739
Lines 241744 241813 +69
Branches 45564 45579 +15
==========================================
+ Hits 218149 218194 +45
- Misses 15115 15171 +56
+ Partials 8480 8448 -32
🚀 New features to boost your workflow:
|
|
@pimterry Could you take a look at this and evaluate this pr proposal? Thanks ! |
|
Sorry I haven't reviewed this yet @Archkon. I think it does match the description before, but I did some digging and I think there's an existing bug with 'use strict';
const assert = require('assert');
const http = require('http');
const net = require('net');
// A server that never reads the request body and aborts the connection.
const server = net.createServer((socket) => socket.destroy());
server.listen(0, () => {
const req = http.request({ port: server.address().port, method: 'POST' });
let writeError = null;
let finishEmitted = false;
req.on('finish', () => { finishEmitted = true; });
req.on('error', () => {});
req.on('close', () => {
server.close();
// The write failed, so the body was never flushed to the socket.
assert.strictEqual(writeError.code, 'EPIPE');
assert.strictEqual(req.writableFinished, false,
'writableFinished is true after a failed write');
assert.strictEqual(finishEmitted, false,
"'finish' was emitted after a failed write");
});
// 1 MiB, so the write cannot fit in the socket buffers and must fail.
req.write(Buffer.alloc(1024 * 1024), (err) => { writeError = err; });
req.end();
});If you tweak your tests slightly you'll hit the same thing. This seems to be an existing bug, but it doesn't normally matter because error emits first and we don't base anything on writableFinished. Once we do, this will swallow write errors just like before. Do you have a little time to take a look? |
Ok, but I was busy with other pr so I think this would be delayed a bit to solve |
|
I've opened a separate PR to fix writableFinished: #64847. Once that's merged, I think this will work correctly. |
Fine,I hope this would push this pr forward smoothly |
Alternative PR to follow-up #64507
Follow-up to: #64507
Original PR Refs: #64278
Fixes: #64272
Refs:#64511
Refs: libuv/libuv#5196
Refs: #64507 (comment)
Refs: #64511 (comment)