Commit 1caad8efb4c for nodejs
commit 1caad8efb4c05d98e303a8fe4058bb2c14468a62
Author: James M Snell <jasnell@gmail.com>
Date: Sat Oct 3 15:10:07 2026 +0000
quic: reject closed stream writer writes with a TypeError
The spec for stream/iter Writers (write(), step 2) requires writes to
a closed writer to reject with a TypeError, as the push(), broadcast()
and FileHandle writers do. The QUIC stream writer rejected write() and
writev() with a plain ERR_INVALID_STATE Error. Use its TypeError
variant; the error code is unchanged.
Assisted-by: OpenCode
Signed-off-by: James M Snell <jasnell@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66483
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
diff --git a/lib/internal/quic/quic.js b/lib/internal/quic/quic.js
index 633e1f4e4de..d163311dc18 100644
--- a/lib/internal/quic/quic.js
+++ b/lib/internal/quic/quic.js
@@ -2332,7 +2332,7 @@ class QuicStream {
async function writeAsync(chunk, signal) {
if (errored) throw error;
if (closed || ending || stream.#inner.state.writeEnded) {
- throw new ERR_INVALID_STATE('Writer is closed');
+ throw new ERR_INVALID_STATE.TypeError('Writer is closed');
}
signal?.throwIfAborted();
@@ -2358,7 +2358,7 @@ class QuicStream {
await waitForDrain(signal);
if (errored) throw error;
if (closed || stream.#inner.state.writeEnded) {
- throw new ERR_INVALID_STATE('Writer is closed');
+ throw new ERR_INVALID_STATE.TypeError('Writer is closed');
}
signal?.throwIfAborted();
if (writeConverted(chunks, token)) return;
@@ -2402,7 +2402,7 @@ class QuicStream {
async function writevAsync(chunks, signal) {
if (errored) throw error;
if (closed || ending || stream.#inner.state.writeEnded) {
- throw new ERR_INVALID_STATE('Writer is closed');
+ throw new ERR_INVALID_STATE.TypeError('Writer is closed');
}
signal?.throwIfAborted();
diff --git a/test/parallel/test-quic-stream-writer-api.mjs b/test/parallel/test-quic-stream-writer-api.mjs
index 352ee29ef59..26f240e4878 100644
--- a/test/parallel/test-quic-stream-writer-api.mjs
+++ b/test/parallel/test-quic-stream-writer-api.mjs
@@ -104,6 +104,11 @@ await clientSession.opened;
{ code: 'ERR_INVALID_ARG_TYPE' },
);
assert.strictEqual(w.endSync(), 12);
+ // Writes after the writer is closed reject with a TypeError.
+ await assert.rejects(w.write('closed'),
+ { code: 'ERR_INVALID_STATE', name: 'TypeError' });
+ await assert.rejects(w.writev(['closed']),
+ { code: 'ERR_INVALID_STATE', name: 'TypeError' });
for await (const _ of stream) { /* drain */ } // eslint-disable-line no-unused-vars
await stream.closed;
}