diff --git a/lib/internal/webstreams/readablestream.js b/lib/internal/webstreams/readablestream.js index 0746d44171fed0..bea1084bdd72ad 100644 --- a/lib/internal/webstreams/readablestream.js +++ b/lib/internal/webstreams/readablestream.js @@ -1911,9 +1911,12 @@ function readableStreamDefaultControllerError(controller, error) { function readableStreamDefaultControllerCancelSteps(controller, reason) { resetQueue(controller); - const result = controller[kState].cancelAlgorithm(reason); - readableStreamDefaultControllerClearAlgorithms(controller); - return result; + try { + const result = controller[kState].cancelAlgorithm(reason); + return result; + } finally { + readableStreamDefaultControllerClearAlgorithms(controller); + } } function readableStreamDefaultControllerPullSteps(controller, readRequest) { diff --git a/test/parallel/test-whatwg-readablestream.js b/test/parallel/test-whatwg-readablestream.js index 13261fe6b7ca84..cef3eca6ed2733 100644 --- a/test/parallel/test-whatwg-readablestream.js +++ b/test/parallel/test-whatwg-readablestream.js @@ -80,6 +80,36 @@ const { assert(r.locked); } +{ + // Throw error and return rejected promise in `cancel()` method + // would execute same cleanup code + const r1 = new ReadableStream({ + cancel: () => { + return Promise.reject('Cancel Error'); + }, + }); + r1.cancel().finally(common.mustCall(() => { + const controllerState = r1[kState].controller[kState]; + + assert.strictEqual(controllerState.pullAlgorithm, undefined); + assert.strictEqual(controllerState.cancelAlgorithm, undefined); + assert.strictEqual(controllerState.sizeAlgorithm, undefined); + })).catch(() => {}); + + const r2 = new ReadableStream({ + cancel() { + throw new Error('Cancel Error'); + } + }); + r2.cancel().finally(common.mustCall(() => { + const controllerState = r2[kState].controller[kState]; + + assert.strictEqual(controllerState.pullAlgorithm, undefined); + assert.strictEqual(controllerState.cancelAlgorithm, undefined); + assert.strictEqual(controllerState.sizeAlgorithm, undefined); + })).catch(() => {}); +} + { const source = { start: common.mustCall((controller) => {