taler-typescript-core

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

commit 48bbd35d45c3b10cad6f22bc8e3499cf3613334b
parent cee43a6fc5329e048ac49308d0dcecbdb263bb72
Author: Florian Dold <florian@dold.me>
Date:   Wed, 26 Jun 2024 19:41:13 +0200

wallet-core: fix error reporting for cancelled transactions

Diffstat:
Mpackages/idb-bridge/src/util/errors.ts | 2+-
Mpackages/taler-wallet-core/src/query.ts | 32+++++++++++++++++++++++++++++---
2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/packages/idb-bridge/src/util/errors.ts b/packages/idb-bridge/src/util/errors.ts @@ -41,7 +41,7 @@ const messages = { export class AbortError extends Error { constructor(message = messages.AbortError) { super(); - Object.setPrototypeOf(this, ConstraintError.prototype); + Object.setPrototypeOf(this, AbortError.prototype); this.name = "AbortError"; this.message = message; } diff --git a/packages/taler-wallet-core/src/query.ts b/packages/taler-wallet-core/src/query.ts @@ -41,6 +41,7 @@ import { Codec, Logger, openPromise, + safeStringifyException, } from "@gnu-taler/taler-util"; const logger = new Logger("query.ts"); @@ -83,9 +84,17 @@ function requestToPromise(req: IDBRequest): Promise<any> { resolve(req.result); }; req.onerror = () => { - console.error("error in DB request", req.error); + if ( + req.error != null && + "name" in req.error && + req.error.name === "AbortError" + ) { + console.warn("DB request failed, transaction aborted"); + } else { + console.error("error in DB request", req.error); + console.error("Request failed:", stack); + } reject(req.error); - console.error("Request failed:", stack); }; }); } @@ -580,6 +589,7 @@ function runTx<Arg, Res>( let funResult: any = undefined; let gotFunResult = false; let transactionException: any = undefined; + let aborted = false; tx.oncomplete = () => { // This is a fatal error: The transaction completed *before* // the transaction function returned. Likely, the transaction @@ -600,10 +610,19 @@ function runTx<Arg, Res>( unregisterOnCancelled(); }; tx.onerror = () => { + if (cancellationToken.isCancelled) { + return; + } logger.error("error in transaction"); logger.error(`${stack.stack}`); }; tx.onabort = () => { + if (cancellationToken.isCancelled) { + reject( + new CancellationToken.CancellationError(cancellationToken.reason), + ); + return; + } let msg: string; if (tx.error) { msg = `Transaction aborted (transaction error): ${tx.error}`; @@ -612,10 +631,11 @@ function runTx<Arg, Res>( } else { msg = "Transaction aborted (no DB error)"; } + aborted = true; + unregisterOnCancelled(); logger.error(msg); logger.error(`${stack.stack}`); reject(new TransactionAbortedError(msg)); - unregisterOnCancelled(); }; const resP = Promise.resolve().then(() => f(arg, tx)); resP @@ -626,12 +646,18 @@ function runTx<Arg, Res>( .catch((e) => { if (e == TransactionAbort) { logger.trace("aborting transaction"); + tx.abort(); + } else if ("name" in e && e.name === "AbortError") { + console.warn("got AbortError, transaction was aborted"); } else { transactionException = e; console.error("Transaction failed:", e); console.error(stack); tx.abort(); } + }) + .catch((e) => { + console.error("aborting failed:", safeStringifyException(e)); }); }); }