diff --git a/doc/api/stream.md b/doc/api/stream.md index 79a1fc74197625..c79fdd65b39ea0 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1677,7 +1677,8 @@ added: --> * `iterable` {Iterable} Object implementing the `Symbol.asyncIterator` or - `Symbol.iterator` iterable protocol. Throws if a null value is passed. + `Symbol.iterator` iterable protocol. Emits an 'error' event if a null + value is passed. * `options` {Object} Options provided to `new stream.Readable([options])`. By default, `Readable.from()` will set `options.objectMode` to `true`, unless this is explicitly opted out by setting `options.objectMode` to `false`. diff --git a/lib/internal/streams/from.js b/lib/internal/streams/from.js index c4596f3b5af8a3..37954792aefa35 100644 --- a/lib/internal/streams/from.js +++ b/lib/internal/streams/from.js @@ -80,8 +80,10 @@ function from(Readable, iterable, opts) { await close(); } else { const res = await value; - if (res === null) readable.destroy(new ERR_STREAM_NULL_VALUES()); - if (readable.push(res)) { + if (res === null) { + reading = false; + readable.destroy(new ERR_STREAM_NULL_VALUES()); + } else if (readable.push(res)) { next(); } else { reading = false; diff --git a/test/parallel/test-readable-from-iterator-closing.js b/test/parallel/test-readable-from-iterator-closing.js index 0254ccfc163093..02252ffe56854c 100644 --- a/test/parallel/test-readable-from-iterator-closing.js +++ b/test/parallel/test-readable-from-iterator-closing.js @@ -168,18 +168,17 @@ async function closeAfterNullYielded() { const finallyMustCall = mustCall(); const dataMustCall = mustCall(3); - function* infiniteGenerate() { + function* generate() { try { yield 'a'; yield 'a'; yield 'a'; - while (true) yield null; } finally { finallyMustCall(); } } - const stream = Readable.from(infiniteGenerate()); + const stream = Readable.from(generate()); stream.on('data', (chunk) => { dataMustCall();