commit b0afe06ff68bf2f9a16ddbdd70bd96a97bd0d0cd
parent c414146fe31041cad9ce618e3968f27189f95a00
Author: Florian Dold <dold@taler.net>
Date: Tue, 21 Jul 2026 11:03:53 +0200
util: make cancellation exception-safe
One throwing listener stopped every later listener from running and skipped
the disposal. Those listeners destroy sockets, clear timers and abort
native requests.
Diffstat:
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/packages/taler-util/src/CancellationToken.ts b/packages/taler-util/src/CancellationToken.ts
@@ -22,6 +22,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+import { Logger } from "./logging.js";
+
+const logger = new Logger("CancellationToken.ts");
+
const NOOP = () => {};
/**
@@ -148,8 +152,20 @@ class CancellationToken {
if (token._isCancelled) return;
token._isCancelled = true;
token._reason = reason;
- token._callbacks?.forEach((cb) => cb(reason));
- dispose();
+ try {
+ // Listeners release resources -- sockets, timers, native requests.
+ // One of them throwing must not keep the others from running, and
+ // must not surface at whoever requested the cancellation.
+ token._callbacks?.forEach((cb) => {
+ try {
+ cb(reason);
+ } catch (e) {
+ logger.error(`cancellation callback failed: ${e}`);
+ }
+ });
+ } finally {
+ dispose();
+ }
};
const dispose = () => {