stream: give error message if write() cb called twice

Otherwise, this condition would result in an error that just reads
`cb is not a function`, and which additionally could have lost
stack trace context through a `process.nextTick()` call.

PR-URL: https://github.com/nodejs/node/pull/19510
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
Anna Henningsen 2018-03-21 13:01:41 +01:00 committed by Ruben Bridgewater
parent cdfe47b323
commit d111d7b91c
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
2 changed files with 53 additions and 0 deletions

View File

@ -37,6 +37,7 @@ const { getHighWaterMark } = require('internal/streams/state');
const {
ERR_INVALID_ARG_TYPE,
ERR_METHOD_NOT_IMPLEMENTED,
ERR_MULTIPLE_CALLBACK,
ERR_STREAM_CANNOT_PIPE,
ERR_STREAM_DESTROYED,
ERR_STREAM_NULL_VALUES,
@ -449,6 +450,9 @@ function onwrite(stream, er) {
var sync = state.sync;
var cb = state.writecb;
if (typeof cb !== 'function')
throw new ERR_MULTIPLE_CALLBACK();
onwriteStateUpdate(state);
if (er)

View File

@ -0,0 +1,49 @@
'use strict';
const common = require('../common');
const { Writable } = require('stream');
{
// Sync + Sync
const writable = new Writable({
write: common.mustCall((buf, enc, cb) => {
cb();
common.expectsError(cb, {
code: 'ERR_MULTIPLE_CALLBACK',
type: Error
});
})
});
writable.write('hi');
}
{
// Sync + Async
const writable = new Writable({
write: common.mustCall((buf, enc, cb) => {
cb();
process.nextTick(() => {
common.expectsError(cb, {
code: 'ERR_MULTIPLE_CALLBACK',
type: Error
});
});
})
});
writable.write('hi');
}
{
// Async + Async
const writable = new Writable({
write: common.mustCall((buf, enc, cb) => {
process.nextTick(cb);
process.nextTick(() => {
common.expectsError(cb, {
code: 'ERR_MULTIPLE_CALLBACK',
type: Error
});
});
})
});
writable.write('hi');
}