-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http: align destroy w streams #32182
Conversation
Streams that are prematurely destroyed without error through .destroy() do usually not emit an error. Align ClientRequest with this behavior.
afea05b
to
fa3b428
Compare
This comment has been minimized.
This comment has been minimized.
I'm not 100% sure this is a good idea since I suppose people are used to Though I would much prefer the behavior proposed in this PR. |
2144f3f
to
7ef95e4
Compare
@@ -375,9 +375,6 @@ function _destroy(req, socket, err) { | |||
socket.destroy(err); | |||
} else { | |||
socket.emit('free'); | |||
if (!req.aborted && !err) { | |||
err = connResetException('socket hang up'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like to remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason? If I call e.g. .destroy()
on a fs
stream it won't cause any error (or any other stream I can think of at the moment).
Is it backwards compat which is you concern?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an informative error that is being removed for no good reason. What's the problem with it? It doesn't work 100% like stream.destroy()
but it is really so problematic to justify a semver-major change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would argue that destroying/aborting a stream is not an error and emitting an error is weird/confusing since for me that would indicate something went wrong / unexpected happened.
I do agree that the worth of the change is questionable though.
Just to give some motivation to this change. Most people (as far as I know) currently use |
|
Ah, I forgot about that. Got it. I'll leave this open for a few more days in case anyone else has further input and close it otherwise. |
@@ -58,8 +58,7 @@ const assert = require('assert'); | |||
server.listen(0, common.mustCall(() => { | |||
const options = { port: server.address().port }; | |||
const req = http.get(options, common.mustNotCall()); | |||
req.on('error', common.mustCall((err) => { | |||
assert.strictEqual(err.code, 'ECONNRESET'); | |||
req.on('close', common.mustCall((err) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change is not correct.
A user is currently adding req.on('error')
and req.on('response')
. They are not adding req.on('close')
.
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This confuses me a little though, abort()
is what most people use (I think?) and then according to your comment above they are already broken.
I think we have two options here:
- Make
destroy()
not force an error. (This PR currently) - Make
abort()
force an error.
Having the two of them behave differently is confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify, this is not about swallowing errors. This is about forcing an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current behavior of http.request()
implies that either 'error'
is fired or 'response'
is fired. Firing nothing wil definitely create a memory leak.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then abort()
has been broken for a long time, because you can call abort()
and get neither 'error'
nor 'response'
.
This happens if abort()
is called before the request has received a socket
(previously through the short circuit in onSocket
).
Should I change this PR to fix that instead?
Firing nothing wil definitely create a memory leak.
'close'
is always fired, but I think I get your point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm talking about code that has already been written and will break in subtle ways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll open a separate PR to fix abort
This further aligns ClientRequest with streams
Streams that are prematurely destroyed without
error through .destroy() do usually not emit
an error.
Align ClientRequest with this behavior.
This changes the behavior to not error when:
abort()
fromreq.socket
has been assigned untilreq.res
has been assigned.destroy()
untilreq.res
has been assigned.Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes