-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
stream: fix multiple destroy()
calls
#29197
Conversation
cb01471
to
6bd51b0
Compare
If this PR is rejected, my opinion is that we should not fix/change the behaviour for |
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.
LGTM
@Trott: That travis failure is weird...? |
CITGM results look worse than they are because AIX ran out of space? (/ping @nodejs/build @nodejs/citgm to check that I'm not reading the results wrong.) |
I'm 👎 on this. The reason is that it will make valid errors to be swallowed. For example consider this case:
|
@lpinca: I'm of the opposite opinion. I'd rather not crash the user if he doesn't expect the error. I've had a few crashes in production due to unexpected errors I don't care about. I really have trouble with our junior developers not considering this behaviour. However, if we don't do this, would you agree atleast that we do not do the referenced change (the swallow error part) in
EDIT: I'm inserting the relevant parts in this thread to keep the conversation in one place:
|
Yes 😄 I have code that relies on current behavior of emitting errors if |
Let's see if we can get any other feedback in the opposite direction. Otherwise I will update and close PR's accordingly (unless anyone objects). |
@Trott: Can we put this on the TSC agenda? My main problem is consistency, Another thing to keep in mind is that with The question is how do we handle errors in relation to
Should probably explicitly document this somewhere? (The |
|
@ronag can you please provide a clearer questions to the TSC? Something that can boil down to a "yes/no" decision. |
What I'm asking for is a set of bullet points on how Should it be:
This is what stream Or should we be even more "helpful":
See #29211 for an example how this could be implemented. Or something else? So I guess the "yes/no" question is: should we avoid (from the users perspective) "unexpected" errors after |
For context this is what we use internally for all const once = require('once')
const noop = () => {}
// If you want to know about errors, pass callback.
module.exports = function destroy (self, err, callback) {
callback = callback ? once(callback) : null
// Ensure no uncaught exception if we don't care about errors.
self.on('error', callback || noop)
if (callback) {
self
// node doesn't always implement destroy with callback
.on('close', callback)
// node doesn't always emit 'close'
// use nextTick and "hope" 'close' is emitted by then.
.on('end', () => process.nextTick(callback))
}
if (typeof self.abort === 'function') {
// TODO: err is lost
self.abort() // Fix for ClientRequest.
} else {
self.destroy(err, callback)
}
} |
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.
Making my 👎 explicit so this is not landed by mistake.
CI: yellow |
@Trott: second opinion on CI & CITGM? I think yellow CI can land? |
Yes, yellow CI can land. |
Landed in 311e12b |
Previously destroy could be called multiple times causing inconsistent and hard to predict behavior. Furthermore, since the stream _destroy implementation can only be called once, the behavior of applying destroy multiple times becomes unclear. This changes so that only the first destroy() call is executed and any subsequent calls are noops. PR-URL: #29197 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This behavior is no longer valid as of nodejs/node#29197
This is a nice change, but I am missing a history note about the change. Based on the current documentation, I called |
Refs: #29197 (comment) PR-URL: #35326 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rich Trott <[email protected]>
Refs: #29197 (comment) PR-URL: #35326 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rich Trott <[email protected]>
Refs: nodejs#29197 (comment) PR-URL: nodejs#35326 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Rich Trott <[email protected]>
Update: This PR has changed (again), see #29197 (comment).
Update (via@Fishrock123
): This PR has changed, see #29197 (comment)Emitting
'error'
afterdestroy()
can surprise the user and lead to unexpected crashes.In #20077 we concluded that we should not emit any errors after
abort()
and then in #28683 we agreed thatabort()
isdestroy()
. Hence, streams should not emit'error'
afterdestroy()
for the same reasons as in #20077.Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes