mirror of
https://github.com/nodejs/node.git
synced 2025-05-04 23:42:17 +00:00
stream: Fix double pipe error emit
If an error listener is added to a stream using once() before it is piped, it is invoked and removed during pipe() but before pipe() sees it which causes it to be emitted again. Fixes #4155 #4978
This commit is contained in:
parent
366baedfd8
commit
23d92ec88e
4
lib/_stream_readable.js
Normal file → Executable file
4
lib/_stream_readable.js
Normal file → Executable file
@ -511,9 +511,11 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
|
||||
|
||||
// if the dest has an error, then stop piping into it.
|
||||
// however, don't suppress the throwing behavior for this.
|
||||
// check for listeners before emit removes one-time listeners.
|
||||
var errListeners = EE.listenerCount(dest, 'error');
|
||||
function onerror(er) {
|
||||
unpipe();
|
||||
if (EE.listenerCount(dest, 'error') === 0)
|
||||
if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0)
|
||||
dest.emit('error', er);
|
||||
}
|
||||
dest.once('error', onerror);
|
||||
|
64
test/simple/test-stream2-pipe-error-once-listener.js
Executable file
64
test/simple/test-stream2-pipe-error-once-listener.js
Executable file
@ -0,0 +1,64 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
var common = require('../common.js');
|
||||
var assert = require('assert');
|
||||
|
||||
var util = require('util');
|
||||
var stream = require('stream');
|
||||
|
||||
|
||||
var Read = function() {
|
||||
stream.Readable.call(this);
|
||||
};
|
||||
util.inherits(Read, stream.Readable);
|
||||
|
||||
Read.prototype._read = function(size) {
|
||||
this.push('x');
|
||||
this.push(null);
|
||||
};
|
||||
|
||||
|
||||
var Write = function() {
|
||||
stream.Writable.call(this);
|
||||
};
|
||||
util.inherits(Write, stream.Writable);
|
||||
|
||||
Write.prototype._write = function(buffer, encoding, cb) {
|
||||
this.emit('error', new Error('boom'));
|
||||
this.emit('alldone');
|
||||
};
|
||||
|
||||
var read = new Read();
|
||||
var write = new Write();
|
||||
|
||||
write.once('error', function(err) {});
|
||||
write.once('alldone', function(err) {
|
||||
console.log('ok');
|
||||
});
|
||||
|
||||
process.on('exit', function(c) {
|
||||
console.error('error thrown even with listener');
|
||||
});
|
||||
|
||||
read.pipe(write);
|
||||
|
Loading…
Reference in New Issue
Block a user