| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent db150b2 commit 5632446
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -72,7 +72,6 @@ const { | |||
| 72 | 72 | const assert = require('internal/assert'); | |
| 73 | 73 | ||
| 74 | 74 | const kSkipThrow = Symbol('kSkipThrow'); | |
| 75 | - | ||
| 76 | 75 | const getNonWritablePropertyDescriptor = (value) => { | |
| 77 | 76 | return { | |
| 78 | 77 | __proto__: null, | |
@@ -524,7 +523,12 @@ function transformStreamDefaultControllerError(controller, error) { | |||
| 524 | 523 | ||
| 525 | 524 | async function transformStreamDefaultControllerPerformTransform(controller, chunk) { | |
| 526 | 525 | try { | |
| 527 | - return await controller[kState].transformAlgorithm(chunk, controller); | ||
| 526 | + const transformAlgorithm = controller[kState].transformAlgorithm; | ||
| 527 | + if (transformAlgorithm === undefined) { | ||
| 528 | + // Algorithms were cleared by a concurrent cancel/abort/close. | ||
| 529 | + return; | ||
| 530 | + } | ||
| 531 | + return await transformAlgorithm(chunk, controller); | ||
| 528 | 532 | } catch (error) { | |
| 529 | 533 | transformStreamError(controller[kState].stream, error); | |
| 530 | 534 | throw error; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,51 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + require('../common'); | ||
| 4 | + const { test } = require('node:test'); | ||
| 5 | + const assert = require('node:assert'); | ||
| 6 | + const { TransformStream } = require('stream/web'); | ||
| 7 | + const { setTimeout } = require('timers/promises'); | ||
| 8 | + | ||
| 9 | + // https://github.com/nodejs/node/issues/62036 | ||
| 10 | + | ||
| 11 | + test('Late write racing with reader.cancel() should not throw an internal TypeError', async () => { | ||
| 12 | + const stream = new TransformStream({ | ||
| 13 | + transform(chunk, controller) { | ||
| 14 | + controller.enqueue(chunk); | ||
| 15 | + }, | ||
| 16 | + }); | ||
| 17 | + | ||
| 18 | + await setTimeout(0); | ||
| 19 | + | ||
| 20 | + const reader = stream.readable.getReader(); | ||
| 21 | + const writer = stream.writable.getWriter(); | ||
| 22 | + | ||
| 23 | + // Release backpressure. | ||
| 24 | + const pendingRead = reader.read(); | ||
| 25 | + | ||
| 26 | + // Simulate client disconnect / shutdown. | ||
| 27 | + const pendingCancel = reader.cancel(new Error('client disconnected')); | ||
| 28 | + | ||
| 29 | + // Late write racing with cancel. | ||
| 30 | + const pendingLateWrite = writer.write('late-write'); | ||
| 31 | + | ||
| 32 | + const [ | ||
| 33 | + readResult, | ||
| 34 | + cancelResult, | ||
| 35 | + lateWriteResult, | ||
| 36 | + ] = await Promise.allSettled([ | ||
| 37 | + pendingRead, | ||
| 38 | + pendingCancel, | ||
| 39 | + pendingLateWrite, | ||
| 40 | + ]); | ||
| 41 | + | ||
| 42 | + assert.strictEqual(readResult.status, 'fulfilled'); | ||
| 43 | + assert.strictEqual(cancelResult.status, 'fulfilled'); | ||
| 44 | + if (lateWriteResult.status === 'rejected') { | ||
| 45 | + const err = lateWriteResult.reason; | ||
| 46 | + const isNotAFunction = err instanceof TypeError && | ||
| 47 | + /transformAlgorithm is not a function/.test(err.message); | ||
| 48 | + assert.ok(!isNotAFunction, | ||
| 49 | + `Internal implementation error leaked: ${err.message}`); | ||
| 50 | + } | ||
| 51 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments