-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
The 'error'
event can be emitted more than once when using writable.destroy()
#26015
Comments
This seems to fix the issue without breaking any existing tests diff --git a/lib/internal/streams/destroy.js b/lib/internal/streams/destroy.js
index 0c652be9dd..200c75459a 100644
--- a/lib/internal/streams/destroy.js
+++ b/lib/internal/streams/destroy.js
@@ -10,10 +10,15 @@ function destroy(err, cb) {
if (readableDestroyed || writableDestroyed) {
if (cb) {
cb(err);
- } else if (err &&
- (!this._writableState || !this._writableState.errorEmitted)) {
- process.nextTick(emitErrorNT, this, err);
+ } else if (err) {
+ if (!this._writableState) {
+ process.nextTick(emitErrorNT, this, err);
+ } else if (!this._writableState.errorEmitted) {
+ this._writableState.errorEmitted = true;
+ process.nextTick(emitErrorNT, this, err);
+ }
}
+
return this;
}
@@ -31,9 +36,13 @@ function destroy(err, cb) {
this._destroy(err || null, (err) => {
if (!cb && err) {
- process.nextTick(emitErrorAndCloseNT, this, err);
- if (this._writableState) {
+ if (!this._writableState) {
+ process.nextTick(emitErrorAndCloseNT, this, err);
+ } else if (!this._writableState.errorEmitted) {
this._writableState.errorEmitted = true;
+ process.nextTick(emitErrorAndCloseNT, this, err);
+ } else {
+ process.nextTick(emitCloseNT, this);
}
} else if (cb) {
process.nextTick(emitCloseNT, this); but is there a reason for having no guard at all for readable only streams? |
cc: @nodejs/streams |
The time needed for making it happen and dealing with the potential ecosystem breakage. If you got some stretch of time, send a PR! |
@lpinca can you PR the changes in #26015 (comment)? |
Yes, will do. |
Prevent the `'error'` event from being emitted multiple times if `writable.destroy()` is called with an error before the `_destroy()` callback is called. Emit the first error, discard all others. Fixes: nodejs#26015
Prevent the `'error'` event from being emitted multiple times if `writable.destroy()` is called with an error before the `_destroy()` callback is called. Emit the first error, discard all others. PR-URL: nodejs#26057 Fixes: nodejs#26015 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
Prevent the `'error'` event from being emitted multiple times if `writable.destroy()` is called with an error before the `_destroy()` callback is called. Emit the first error, discard all others. PR-URL: #26057 Fixes: #26015 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
Prevent the `'error'` event from being emitted multiple times if `writable.destroy()` is called with an error before the `_destroy()` callback is called. Emit the first error, discard all others. PR-URL: nodejs#26057 Backport-PR-URL: nodejs#28000 Fixes: nodejs#26015 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
Prevent the `'error'` event from being emitted multiple times if `writable.destroy()` is called with an error before the `_destroy()` callback is called. Emit the first error, discard all others. PR-URL: #26057 Backport-PR-URL: #28000 Fixes: #26015 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
The
'error'
event can be emitted multiple times when usingwritable.destroy()
if the_destroy()
callback is called asynchronously. Here is a test case:Actual result:
The
'error'
event is emitted twice.Expected result:
The
'error'
event is emitted only once.This is because the
_writableState.errorEmitted
guard is set totrue
when the callback is called.The text was updated successfully, but these errors were encountered: