Skip to content

Commit a022b4d

Browse files
committed
stream: call end(cb) callback after destroy
Don't deadlock calls to end(cb) after destroy(). This only partly fixes the problem in order to minimize breakage.
1 parent ddcd235 commit a022b4d

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

lib/_stream_writable.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,20 @@ Writable.prototype.end = function(chunk, encoding, cb) {
591591
encoding = null;
592592
}
593593

594-
if (chunk !== null && chunk !== undefined)
594+
if (chunk !== null && chunk !== undefined) {
595595
this.write(chunk, encoding);
596+
} else if (state.destroyed) {
597+
// TODO(ronag): Condition is for backwards compat.
598+
if (state.errorEmitted || state.finished) {
599+
const err = new ERR_STREAM_DESTROYED('end');
600+
if (typeof cb === 'function') {
601+
process.nextTick(cb, err);
602+
}
603+
// TODO(ronag): Disabled for backwards compat.
604+
// errorOrDestroy(this, err, true);
605+
return;
606+
}
607+
}
596608

597609
// .end() fully uncorks
598610
if (state.corked) {

test/parallel/test-stream-writable-destroy.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,33 @@ const assert = require('assert');
292292
}));
293293
write.uncork();
294294
}
295+
296+
{
297+
// Call end(cb) after error & destroy
298+
299+
const write = new Writable({
300+
write(chunk, enc, cb) { cb(new Error('asd')); }
301+
});
302+
write.on('error', common.mustCall(() => {
303+
write.destroy();
304+
write.end(common.mustCall((err) => {
305+
assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED');
306+
}));
307+
}));
308+
write.write('asd');
309+
}
310+
311+
{
312+
// Call end(cb) after finish & destroy
313+
314+
const write = new Writable({
315+
write(chunk, enc, cb) { cb(); }
316+
});
317+
write.on('finish', common.mustCall(() => {
318+
write.destroy();
319+
write.end(common.mustCall((err) => {
320+
assert.strictEqual(err.code, 'ERR_STREAM_DESTROYED');
321+
}));
322+
}));
323+
write.end();
324+
}

0 commit comments

Comments
 (0)