Skip to content

Commit 2b05573

Browse files
committed
stream: validate backpressure option at construction time
Invalid backpressure values like `'banana'` would fall through switch statements at write time with a confusing `ERR_INVALID_STATE` error about "`writeSync` should have handled non-strict policy". Add `validateBackpressure()` in utils.js and call it from the `PushQueue`, `BroadcastImpl`, `ShareImpl`, and `SyncShareImpl` constructors. Invalid values now throw `ERR_INVALID_ARG_VALUE` immediately at construction.
1 parent f2ada96 commit 2b05573

5 files changed

Lines changed: 42 additions & 0 deletions

File tree

lib/internal/streams/iter/broadcast.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const {
4949
const {
5050
allUint8Array,
5151
toUint8Array,
52+
validateBackpressure,
5253
} = require('internal/streams/iter/utils');
5354

5455
const {
@@ -111,6 +112,7 @@ class BroadcastImpl {
111112
#writer = null;
112113

113114
constructor(options) {
115+
validateBackpressure(options.backpressure);
114116
this.#options = options;
115117
this[kOnBufferDrained] = null;
116118
}

lib/internal/streams/iter/push.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const {
2929
const {
3030
toUint8Array,
3131
allUint8Array,
32+
validateBackpressure,
3233
} = require('internal/streams/iter/utils');
3334

3435
const {
@@ -73,6 +74,7 @@ class PushQueue {
7374
constructor(options = {}) {
7475
this.#highWaterMark = MathMax(1, options.highWaterMark ?? 4);
7576
this.#backpressure = options.backpressure ?? 'strict';
77+
validateBackpressure(this.#backpressure);
7678
this.#signal = options.signal;
7779
this.#abortHandler = undefined;
7880

lib/internal/streams/iter/share.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const {
3737

3838
const {
3939
parsePullArgs,
40+
validateBackpressure,
4041
} = require('internal/streams/iter/utils');
4142

4243
const {
@@ -350,6 +351,7 @@ class SyncShareImpl {
350351
#cancelled = false;
351352

352353
constructor(source, options) {
354+
validateBackpressure(options.backpressure);
353355
this.#source = source;
354356
this.#options = options;
355357
}

lib/internal/streams/iter/utils.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ const {
1010
} = primordials;
1111

1212
const { TextEncoder } = require('internal/encoding');
13+
const {
14+
codes: {
15+
ERR_INVALID_ARG_VALUE,
16+
},
17+
} = require('internal/errors');
1318

1419
// Shared TextEncoder instance for string conversion.
1520
const encoder = new TextEncoder();
@@ -112,10 +117,26 @@ function parsePullArgs(args) {
112117
return { transforms: args, options: undefined };
113118
}
114119

120+
/**
121+
* Validate backpressure option value.
122+
* @param {string} value
123+
*/
124+
function validateBackpressure(value) {
125+
if (value !== 'strict' &&
126+
value !== 'block' &&
127+
value !== 'drop-oldest' &&
128+
value !== 'drop-newest') {
129+
throw new ERR_INVALID_ARG_VALUE(
130+
'options.backpressure', value,
131+
'must be "strict", "block", "drop-oldest", or "drop-newest"');
132+
}
133+
}
134+
115135
module.exports = {
116136
toUint8Array,
117137
allUint8Array,
118138
concatBytes,
119139
isPullOptions,
120140
parsePullArgs,
141+
validateBackpressure,
121142
};

test/parallel/test-stream-iter-push.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,19 @@ Promise.all([
352352
testCancelledWriteRemovedFromQueue(),
353353
testOndrainResolvesFalseOnConsumerBreak(),
354354
testOndrainRejectsOnConsumerThrow(),
355+
testInvalidBackpressure(),
355356
]).then(common.mustCall());
357+
358+
async function testInvalidBackpressure() {
359+
assert.throws(() => push({ backpressure: 'banana' }), {
360+
code: 'ERR_INVALID_ARG_VALUE',
361+
});
362+
assert.throws(() => push({ backpressure: '' }), {
363+
code: 'ERR_INVALID_ARG_VALUE',
364+
});
365+
366+
// Valid values should not throw
367+
for (const bp of ['strict', 'block', 'drop-oldest', 'drop-newest']) {
368+
push({ backpressure: bp });
369+
}
370+
}

0 commit comments

Comments
 (0)