diff --git a/packages/taler-util/src/errors.ts b/packages/taler-util/src/errors.ts index a27970173..36f8069c6 100644 --- a/packages/taler-util/src/errors.ts +++ b/packages/taler-util/src/errors.ts @@ -101,8 +101,21 @@ export interface DetailsMap { /** * The taler:// action that the request expected, if the URI parsed * but denotes something else. + * + * Set ONLY in that case. Setting it for every parse failure says the + * URI denotes some other action when it may well denote the right one + * and be malformed for an unrelated reason, which is actively + * misleading: a well-formed-looking `taler://pay-push/...` reported + * `expectedAction: "pay-push"`, i.e. "this is not a pay-push URI" + * about a pay-push URI. */ expectedAction?: string; + /** + * The name of the `TalerUriParseError` the parser actually returned, + * e.g. `"INVALID_TARGET_PATH"`. Without it every failure is + * indistinguishable at the API boundary. + */ + parseError?: string; }; [TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR]: { requestUrl: string; diff --git a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts index 4095cfe56..d3592074c 100644 --- a/packages/taler-wallet-core/src/pay-peer-pull-debit.ts +++ b/packages/taler-wallet-core/src/pay-peer-pull-debit.ts @@ -47,6 +47,7 @@ import { TalerPayPullUri, TalerPreciseTimestamp, TalerUriAction, + TalerUriParseError, TalerUris, Transaction, TransactionAction, @@ -1879,16 +1880,34 @@ async function internalPreparePeerPullDebit( let uri: TalerPayPullUri | undefined; if (req.talerUri) { - uri = Result.orUndefined( - TalerUris.parseRestricted(req.talerUri, TalerUriAction.PayPull), + const parsedUriRes = TalerUris.parseRestricted( + req.talerUri, + TalerUriAction.PayPull, ); - if (!uri) { + if (Result.isError(parsedUriRes)) { + // Report WHY it failed. `Result.orUndefined` threw the parse error + // away, and the message below was emitted for every cause, so a + // malformed-but-correctly-typed URI was reported as having the wrong + // action -- see the note on `expectedAction` in errors.ts. + const wrongAction = + parsedUriRes.error === TalerUriParseError.UNEXPECTED_ACTION; throw TalerError.fromDetail( TalerErrorCode.WALLET_TALER_URI_MALFORMED, - { talerUri: req.talerUri, expectedAction: TalerUriAction.PayPull }, - "expected a taler://pay-pull URI", + { + talerUri: req.talerUri, + ...(wrongAction + ? { expectedAction: TalerUriAction.PayPull } + : {}), + parseError: TalerUriParseError[parsedUriRes.error], + }, + wrongAction + ? "expected a taler://pay-pull URI" + : `malformed taler://pay-pull URI: ${ + TalerUriParseError[parsedUriRes.error] + }`, ); } + uri = parsedUriRes.value; } let parsedTxId: string | undefined; diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/pay-peer-push-credit.ts index 40aba243a..d7c72063a 100644 --- a/packages/taler-wallet-core/src/pay-peer-push-credit.ts +++ b/packages/taler-wallet-core/src/pay-peer-push-credit.ts @@ -36,6 +36,7 @@ import { TalerPayPushUri, TalerPreciseTimestamp, TalerUriAction, + TalerUriParseError, TalerUris, Transaction, TransactionAction, @@ -563,16 +564,34 @@ async function internalPreparePeerPushCredit( let uri: TalerPayPushUri | undefined; if (req.talerUri) { - uri = Result.orUndefined( - TalerUris.parseRestricted(req.talerUri, TalerUriAction.PayPush), + const parsedUriRes = TalerUris.parseRestricted( + req.talerUri, + TalerUriAction.PayPush, ); - if (!uri) { + if (Result.isError(parsedUriRes)) { + // Report WHY it failed. `Result.orUndefined` threw the parse error + // away, and the message below was emitted for every cause, so a + // malformed-but-correctly-typed URI was reported as having the wrong + // action -- see the note on `expectedAction` in errors.ts. + const wrongAction = + parsedUriRes.error === TalerUriParseError.UNEXPECTED_ACTION; throw TalerError.fromDetail( TalerErrorCode.WALLET_TALER_URI_MALFORMED, - { talerUri: req.talerUri, expectedAction: TalerUriAction.PayPush }, - "expected a taler://pay-push URI", + { + talerUri: req.talerUri, + ...(wrongAction + ? { expectedAction: TalerUriAction.PayPush } + : {}), + parseError: TalerUriParseError[parsedUriRes.error], + }, + wrongAction + ? "expected a taler://pay-push URI" + : `malformed taler://pay-push URI: ${ + TalerUriParseError[parsedUriRes.error] + }`, ); } + uri = parsedUriRes.value; } let parsedTxId: string | undefined;