From 96051ff103f2928d589e4eb34e36ebe64b05ef9e Mon Sep 17 00:00:00 2001 From: Gang Chen <13298548+MoonBall@users.noreply.github.com> Date: Sat, 26 Feb 2022 21:19:42 +0800 Subject: [PATCH] lib: clean after the cancel algorithm throw error PR-URL: https://github.com/nodejs/node/pull/41366 Reviewed-By: James M Snell Reviewed-By: Robert Nagy --- lib/internal/webstreams/readablestream.js | 9 ++++--- test/parallel/test-whatwg-readablestream.js | 30 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) 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) => {