Skip to content

Commit 96e546b

Browse files
stream: fix ERR_INVALID_STATE when cancelling Readable.toWeb()
When a web ReadableStream returned by Readable.toWeb() is cancelled while the underlying Readable is actively producing data, a pending onData callback can still fire after the controller has been closed and attempt to enqueue a chunk, throwing ERR_INVALID_STATE. Check wasCanceled in the onData handler and return early to avoid calling controller.enqueue() on a closed controller. Refs: #54205
1 parent ed05549 commit 96e546b

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

lib/internal/webstreams/adapters.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ function newReadableStreamFromStreamReadable(streamReadable, options = kEmptyObj
507507
let wasCanceled = false;
508508

509509
function onData(chunk) {
510+
if (wasCanceled) return;
510511
// Copy the Buffer to detach it from the pool.
511512
if (Buffer.isBuffer(chunk) && !objectMode)
512513
chunk = new Uint8Array(chunk);

test/parallel/test-stream-readable-to-web-termination.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,25 @@ const { Readable } = require('stream');
1010
const reader = Readable.toWeb(r).getReader();
1111
reader.read();
1212
}
13+
14+
// Cancelling a web ReadableStream while the underlying Readable is actively
15+
// producing data should not throw ERR_INVALID_STATE. The onData handler in
16+
// newReadableStreamFromStreamReadable must check wasCanceled before calling
17+
// controller.enqueue(). See: https://github.com/nodejs/node/issues/54205
18+
{
19+
const readable = new Readable({
20+
read() {
21+
this.push(Buffer.alloc(1024));
22+
},
23+
});
24+
25+
const webStream = Readable.toWeb(readable);
26+
const reader = webStream.getReader();
27+
28+
(async () => {
29+
await reader.read();
30+
await reader.read();
31+
reader.releaseLock();
32+
await webStream.cancel();
33+
})();
34+
}

0 commit comments

Comments
 (0)