taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit c414146fe31041cad9ce618e3968f27189f95a00
parent b79efd6f9786ac59089571d18ce88fd262b0b0a1
Author: Florian Dold <dold@taler.net>
Date:   Tue, 21 Jul 2026 11:03:12 +0200

util: test that cancellation is exception-safe

Diffstat:
Apackages/taler-util/src/CancellationToken.test.ts | 38++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+), 0 deletions(-)

diff --git a/packages/taler-util/src/CancellationToken.test.ts b/packages/taler-util/src/CancellationToken.test.ts @@ -0,0 +1,38 @@ +/* + This file is part of GNU Taler + (C) 2026 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import assert from "node:assert"; +import { test } from "node:test"; +import { CancellationToken } from "./CancellationToken.js"; + +test("cancellation notifies every listener even if one throws", (t) => { + const source = CancellationToken.create(); + const ran: string[] = []; + source.token.onCancelled(() => ran.push("first")); + source.token.onCancelled(() => { + throw Error("listener blew up"); + }); + source.token.onCancelled(() => ran.push("third")); + + // Listeners release sockets and clear timers. One badly behaved consumer + // must not keep the others from cleaning up, and must not propagate out of + // cancel() into whoever requested the cancellation. + assert.doesNotThrow(() => source.cancel()); + assert.deepStrictEqual(ran, ["first", "third"]); + assert.strictEqual(source.token.isCancelled, true); + // The token is settled, so its callback set has been released. + assert.strictEqual((source.token as any)._callbacks, undefined); +});