Uh oh!
There was an error while loading. Please reload this page.
http: fix just-merged change that could silently truncate responses - #64507
http: fix just-merged change that could silently truncate responses#64507pimterry wants to merge 2 commits into
Conversation
Signed-off-by: Tim Perry <pimterry@gmail.com>
nodejs-github-bot
commented
Jul 14, 2026
Review requested:
|
Fast-track has been requested by @pimterry. Please 👍 to approve. |
mcollina
commented
Jul 14, 2026
I'm also ok to revert #64278. |
nodejs-github-bot
commented
Jul 14, 2026
pimterry
commented
Jul 14, 2026
I think we can roll forwards instead. The issue is real, and the fix is roughly correct, it just misses a couple of cases en route. AFAICT with some small changes this'll work as intended. That said, I say "cases" plural because I've found another one: if the response is completed but the request is still going, this will now swallow errors we previously emitted on the still open request. That can happen because request/response lifetimes are surprisingly independent, servers can finish responding while the request is still going. Most plausible example: the server could send an HTTP 202 to confirm an upload based on headers alone, before the body is fully delivered, expecting the request to keep writing it out even though the response side is closed. It's definitely weird, but it's valid HTTP AFAICT and I wouldn't be surprised at all if somebody does it and expects to get errors if it goes wrong. Bonus fix for that incoming now. |
Signed-off-by: Tim Perry <pimterry@gmail.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@## main #64507 +/- ##
==========================================
- Coverage 90.23% 90.23% -0.01%
==========================================
Files 741 739 -2 Lines 241692 241668 -24 Branches 45541 45547 +6 ==========================================
- Hits 218097 218073 -24 - Misses 15113 15152 +39 + Partials 8482 8443 -39
🚀 New features to boost your workflow:
|
| if (req) { | ||
| const res = req.res; | ||
| const exchangeComplete = req.writableFinished && res?.complete; |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
| assert(response); | ||
| assert.strictEqual(response.complete, true); | ||
| assert.strictEqual(req.writableFinished, false); | ||
| assert.strictEqual(err.code, 'ECONNRESET'); |
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
pimterry
commented
Jul 15, 2026
@Archkon I'm assuming from your comments on #64511 that you're happy to open a new PR for this once it's reverted? That would be great if so, I'll close this once that's open. Just for reference, I think there's a few key things to cover:
I think the correct logic for the code is now clear enough, the tricky part is writing tests that carefully wait for the write events so they properly cover the original issue, and also validate the various different cases here. It turns out it's quite a complex set of behaviours! In terms of testing it, see what you can come up with to try to fix this, and then open the PR and we can run CI manually to validate it there. Thanks for your work on this. Sorry for all the back and forth but hopefully we'll get something working nicely soon. Feel free to ping if you have questions or want any help. |
This comment was marked as spam.
This comment was marked as spam.
pimterry
commented
Jul 15, 2026
Ah, there are at least two failing tests, that's the confusion. macOS fails on that error test, but For the error test case, yes being flexible on the error codes if they're all reasonable is OK I think. |
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
pimterry
commented
Jul 16, 2026
I think I understand, interesting! I don't have a mac easily available for testing unfortunately. There will just be some difference in packet processing or delivery at the OS level. You'll need to break down smaller repros until you work out exactly where macos differs. Once we know where the timing difference is we can write a test that is stable under those conditions. My expectation is that this is purely a testing issue - it's just hard to reproduce the problem in a clean way without hitting these timing issues. |
This fixes an issue introduced 2 days ago in #64278. With that change, errors that emit after HTTP response headers are received but before the response is completed are swallowed silently.
This PR preserves the core change there, but covers the "response set but not yet completed" window properly so errors here still fire as expected.