-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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: improving error handling #18438
Conversation
/cc @mcollina @nodejs/streams |
doc/api/errors.md
Outdated
<a id="ERR_STREAM_DESTROYED"></a> | ||
### ERR_STREAM_DESTROYED | ||
|
||
An stream method was called that cannot complete cause the stream was been |
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.
Nits:
An stream -> A stream
was been -> has been
lib/_stream_readable.js
Outdated
@@ -106,6 +106,9 @@ function ReadableState(options, stream) { | |||
this.readableListening = false; | |||
this.resumeScheduled = false; | |||
|
|||
// True if the close was already emitted and should not emitted again |
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.
A nit: should not emitted -> should not be emitted
lib/_stream_writable.js
Outdated
@@ -134,6 +134,9 @@ function WritableState(options, stream) { | |||
// True if the error was already emitted and should not be thrown again | |||
this.errorEmitted = false; | |||
|
|||
// True if the close was already emitted and should not emitted again |
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.
A nit: should not emitted -> should not be emitted
@nodejs/http2 ... just a quick note that this will have a relatively small impact on the |
Added docs about the |
lib/internal/http2/core.js
Outdated
// Set close emitted, so the stream destruction does not | ||
// emit them | ||
this._readableState.closeEmitted = true; | ||
this._writableState.closeEmitted = true; |
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 not very fond of this lines. A current goal is to reduce (or totally remove) the number of access to _readableState
and _writableState
. However, this requires it. Maybe emitting 'close'
automatically can be moved to an option?
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 is only because http2 currently emits a 'code' argument with the close event. The idea is to get rid of that in http2 and move the 'code' to a property down the line, but this ensures backwards compat right now.
Should I add a comment explaining that?
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.
What I mean is that in both fs
and http2
for compat reason we need to not emit 'close'
on destroy. I think this might actually be a legit use case, and so we should support it with an option at construction.
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 fs
thing is legit, but we should just get rid of the code in http2
imo, but that's another discussion. I like the idea of an option, adding it.
lib/_stream_readable.js
Outdated
@@ -437,7 +441,8 @@ Readable.prototype.read = function(n) { | |||
if (state.length === 0) | |||
state.needReadable = true; | |||
// call internal read method | |||
this._read(state.highWaterMark); | |||
if (!state.destroyed) |
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 check can me moved in the previous if
block: state.ended || state.reading || state.destroyed
.
lib/_stream_transform.js
Outdated
@@ -132,6 +132,8 @@ function Transform(options) { | |||
} | |||
|
|||
function prefinish() { | |||
if (this._readableState.destroyed) | |||
return; |
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.
can you add one more test for the _flush()
logic and destroy()
? It seems you are fixing a bug here. Or without this change some tests would not pass anymore?
4bc9c16
to
958d5be
Compare
@mcollina fixed your comments |
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 with a nit
lib/net.js
Outdated
@@ -219,6 +226,11 @@ function Socket(options) { | |||
options = { fd: options }; // Legacy interface. | |||
else if (options === undefined) | |||
options = {}; | |||
else | |||
options = copyObject(options); |
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.
You can use Object.assign
.
@mcollina nit fixed |
@mafintosh can you add |
@mcollina fixed the docs |
doc/api/errors.md
Outdated
<a id="ERR_STREAM_DESTROYED"></a> | ||
### ERR_STREAM_DESTROYED | ||
|
||
A stream method was called that cannot complete cause the stream was been |
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.
Seems like cause
should be because
here, I think?
doc/api/errors.md
Outdated
<a id="ERR_STREAM_DESTROYED"></a> | ||
### ERR_STREAM_DESTROYED | ||
|
||
A stream method was called that cannot complete cause the stream was been |
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.
s/cause/because
@mcollina ci seemed to have an issue? |
We are testing in so many system that a botched run happens every now and then. |
6e65b5e
to
1689baf
Compare
Landed as 5e3f516 |
This improves error handling for streams in a few ways. 1. It ensures that no user defined methods (_read, _write, ...) are run after .destroy has been called. 2. It introduces an explicit error to tell the user if they are write to write, etc to the stream after it has been destroyed. 3. It makes streams always emit close as the last thing after they have been destroyed 4. Changes the default _destroy to not gracefully end streams. It also updates net, http2, zlib and fs to the new error handling. PR-URL: #18438 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This is breaking the linter on master
|
This improves error handling for streams in a few ways. 1. It ensures that no user defined methods (_read, _write, ...) are run after .destroy has been called. 2. It introduces an explicit error to tell the user if they are write to write, etc to the stream after it has been destroyed. 3. It makes streams always emit close as the last thing after they have been destroyed 4. Changes the default _destroy to not gracefully end streams. It also updates net, http2, zlib and fs to the new error handling. PR-URL: nodejs#18438 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Anna Henningsen <anna@addaleax.net>
See: nodejs#18438 PR-URL: nodejs#19169 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
See: nodejs#25373 See: nodejs#18438 PR-URL: nodejs#25413 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
stream
This PR improves error handling for streams in a few ways.
close
as the last thing after they have been destroyedEspecially 4. makes it easier for userland modules to handle stream errors as they don't appear as graceful closes anymore. Seen issues being with end-of-stream/pump because of this.