diff --git a/lib/internal/streams/iter/classic.js b/lib/internal/streams/iter/classic.js index 18d1733d6ad648..6f978102d2b645 100644 --- a/lib/internal/streams/iter/classic.js +++ b/lib/internal/streams/iter/classic.js @@ -513,6 +513,16 @@ function fromWritable(writable, options = kNullPrototype) { return (writable.writableLength ?? 0) >= hwm; } + function writeChunks(chunks) { + let ok = true; + for (let i = 0; i < chunks.length; i++) { + const bytes = toUint8Array(chunks[i]); + totalBytes += TypedArrayPrototypeGetByteLength(bytes); + ok = writable.write(bytes); + } + return ok; + } + const writer = { __proto__: null, @@ -608,14 +618,18 @@ function fromWritable(writable, options = kNullPrototype) { return PromiseResolve(); } - if (typeof writable.cork === 'function') writable.cork(); let ok = true; - for (let i = 0; i < chunks.length; i++) { - const bytes = toUint8Array(chunks[i]); - totalBytes += TypedArrayPrototypeGetByteLength(bytes); - ok = writable.write(bytes); + if (typeof writable.cork === 'function' && + typeof writable.uncork === 'function') { + writable.cork(); + try { + ok = writeChunks(chunks); + } finally { + writable.uncork(); + } + } else { + ok = writeChunks(chunks); } - if (typeof writable.uncork === 'function') writable.uncork(); if (ok) return PromiseResolve(); diff --git a/test/parallel/test-stream-iter-writable-interop.js b/test/parallel/test-stream-iter-writable-interop.js index 8a2ead0d0ee579..e7b83ac22841ce 100644 --- a/test/parallel/test-stream-iter-writable-interop.js +++ b/test/parallel/test-stream-iter-writable-interop.js @@ -550,6 +550,21 @@ function testWritevInvalidChunksType() { ); } +// ============================================================================= +// writev() uncorks when chunk validation throws +// ============================================================================= + +function testWritevInvalidChunkUncorks() { + const writable = new Writable({ write(chunk, enc, cb) { cb(); } }); + const writer = fromWritable(writable); + + assert.throws( + () => writer.writev([new Uint8Array([1]), 42]), + { code: 'ERR_INVALID_ARG_TYPE' }, + ); + assert.strictEqual(writable.writableCorked, 0); +} + // ============================================================================= // Cached writer: second call returns same instance // ============================================================================= @@ -638,6 +653,7 @@ testDrainableNull(); testDropOldestThrows(); testInvalidBackpressureThrows(); testWritevInvalidChunksType(); +testWritevInvalidChunkUncorks(); testCachedWriter(); testObjectModeThrows();