commit 0101e703dfb8a4280f8c416db25b333aa64fc6e3
parent 1c92825ed08f60f9c60ed018b73b94e1d843a3ba
Author: Florian Dold <florian@dold.me>
Date: Mon, 28 Apr 2025 02:25:23 +0200
harness: restore old test assertion in denom-unoffered, simplify
Diffstat:
2 files changed, 54 insertions(+), 25 deletions(-)
diff --git a/packages/taler-harness/src/integrationtests/test-denom-unoffered.ts b/packages/taler-harness/src/integrationtests/test-denom-unoffered.ts
@@ -18,14 +18,15 @@
* Imports.
*/
import {
+ codecForTalerErrorDetail,
Duration,
j2s,
Logger,
PreparePayResultType,
succeedOrThrow,
TalerErrorCode,
+ TalerErrorDetail,
TalerMerchantInstanceHttpClient,
- TransactionType,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import {
@@ -123,20 +124,26 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
logger.info(`tx error: ${j2s(tx.error)}`);
- const merchantErrorCode = (tx.error as any).requestError.errorResponse.code;
-
- switch (merchantErrorCode) {
- case TalerErrorCode.MERCHANT_GENERIC_EXCHANGE_TIMEOUT:
- // Merchant didn't receive/process the keys from the exchange yet,
- // merchant's response indicates "timeout" from the exchange
- // request, but in fact the merchant is throttling the request.
- break;
- case TalerErrorCode.MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND:
- // Merchant already managed to re-contact the exchange.
- break;
- default:
- t.fail(`unexpected error code: ${merchantErrorCode}`);
- }
+ t.assertDeepEqual((tx.error as any).requestError.httpStatusCode, 502);
+
+ const merchantErrorResp: TalerErrorDetail = (tx.error as any).requestError
+ .errorResponse;
+
+ t.assertDeepEqual(merchantErrorResp.exchange_http_status, 404);
+
+ t.assertDeepEqual(
+ merchantErrorResp.code,
+ TalerErrorCode.MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS,
+ );
+
+ const exchangeResp = codecForTalerErrorDetail().decode(
+ merchantErrorResp.exchange_reply,
+ );
+
+ t.assertDeepEqual(
+ exchangeResp.code,
+ TalerErrorCode.EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN,
+ );
// Force updating the exchange entry so that the wallet knows about the new denominations.
await walletClient.call(WalletApiOperation.UpdateExchangeEntry, {
@@ -144,10 +151,6 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
force: true,
});
- // await walletClient.call(WalletApiOperation.DeleteTransaction, {
- // transactionId: confirmResp.transactionId,
- // });
-
logger.info(`withdrawing (with new denoms)`);
// Now withdrawal should work again.
@@ -183,15 +186,17 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
const txs = await walletClient.call(WalletApiOperation.GetTransactions, {
sort: "stable-ascending",
- includeRefreshes: true,
});
console.log(JSON.stringify(txs, undefined, 2));
- t.assertDeepEqual(txs.transactions[0].type, TransactionType.Withdrawal);
- t.assertDeepEqual(txs.transactions[1].type, TransactionType.Refresh);
- t.assertDeepEqual(txs.transactions[2].type, TransactionType.Payment);
- t.assertDeepEqual(txs.transactions[3].type, TransactionType.DenomLoss);
- t.assertDeepEqual(txs.transactions[4].type, TransactionType.Withdrawal);
+ const txTypes = txs.transactions.map((x) => x.type);
+
+ t.assertDeepEqual(txTypes, [
+ "withdrawal",
+ "payment",
+ "denom-loss",
+ "withdrawal",
+ ]);
}
runDenomUnofferedTest.suites = ["wallet"];
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -1674,6 +1674,7 @@ async function handleInsufficientFunds(
await ctx.abortTransaction({
code: TalerErrorCode.WALLET_TRANSACTION_PROTOCOL_VIOLATION,
message: "Denomination used in payment became invalid.",
+ errorDetails: err,
});
return TaskRunResult.progress();
} else {
@@ -3407,6 +3408,29 @@ async function processPurchasePay(
}
}
+ if (resp.status === HttpStatusCode.BadGateway) {
+ const err = await readTalerErrorResponse(resp);
+ switch (err.code) {
+ case TalerErrorCode.MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS: {
+ const exchangeEc = (err.exchange_reply as any)?.code;
+ switch (exchangeEc) {
+ case TalerErrorCode.EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN:
+ // We might want to handle this in the future by re-denomination,
+ // for now we just abort.
+ await ctx.abortTransaction({
+ code: TalerErrorCode.WALLET_TRANSACTION_PROTOCOL_VIOLATION,
+ message: "Denomination used in payment became invalid.",
+ errorDetails: err,
+ });
+ return TaskRunResult.progress();
+ }
+ break;
+ }
+ }
+ // We don't know the specific error, so it's safer to retry.
+ return throwUnexpectedRequestError(resp, err);
+ }
+
if (resp.status === HttpStatusCode.UnavailableForLegalReasons) {
logger.warn(`pay transaction aborted, merchant has KYC problems`);
await ctx.abortTransaction(