wallet-core: return pending status instead of error

This allows clients to get the transaction ID of the confirmed payment.
This commit is contained in:
Florian Dold 2023-01-13 00:31:29 +01:00
parent 72ca5ee8dd
commit cbf848dd2a
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
2 changed files with 18 additions and 36 deletions

View File

@ -18,7 +18,7 @@
* Imports.
*/
import { PreparePayResultType, TalerErrorCode } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { Wallet, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
import {
createSimpleTestkudosEnvironment,
@ -55,7 +55,6 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
fulfillment_url: "taler://fulfillment-success/thx",
};
{
const orderResp = await MerchantPrivateApi.createOrder(
merchant,
"default",
@ -86,34 +85,34 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
preparePayResult.status === PreparePayResultType.PaymentPossible,
);
const exc = await t.assertThrowsTalerErrorAsync(async () => {
await wallet.client.call(WalletApiOperation.ConfirmPay, {
proposalId: preparePayResult.proposalId,
});
const confirmResp = await wallet.client.call(WalletApiOperation.ConfirmPay, {
proposalId: preparePayResult.proposalId,
});
const tx = await wallet.client.call(WalletApiOperation.GetTransactionById, {
transactionId: confirmResp.transactionId,
});
t.assertTrue(
exc.hasErrorCode(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED),
tx.error?.code === TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR
);
// FIXME: We might want a more specific error code here!
t.assertDeepEqual(
exc.errorDetail.innerError.code,
TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR,
);
const merchantErrorCode = (exc.errorDetail.innerError.errorResponse as any)
const merchantErrorCode = ((tx.error as any).errorResponse as any)
.code;
t.assertDeepEqual(
merchantErrorCode,
TalerErrorCode.MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND,
);
}
await wallet.client.call(WalletApiOperation.AddExchange, {
exchangeBaseUrl: exchange.baseUrl,
forceUpdate: true,
});
await wallet.client.call(WalletApiOperation.DeleteTransaction, {
transactionId: confirmResp.transactionId,
});
// Now withdrawal should work again.
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });

View File

@ -1625,28 +1625,11 @@ export async function runPayForConfirmPay(
.runReadOnly(async (tx) =>
tx.operationRetries.get(RetryTags.byPaymentProposalId(proposalId)),
);
const maxRetry = 3;
const numRetry = opRetry?.retryInfo.retryCounter ?? 0;
if (
res.errorDetail.code ===
TalerErrorCode.WALLET_PAY_MERCHANT_SERVER_ERROR &&
numRetry < maxRetry
) {
logger.trace("hiding transient error from caller");
// Pretend the operation is pending instead of reporting
// an error, but only up to maxRetry attempts.
await storeOperationPending(
ws,
RetryTags.byPaymentProposalId(proposalId),
);
return {
type: ConfirmPayResultType.Pending,
lastError: opRetry?.lastError,
transactionId: makeTransactionId(TransactionType.Payment, proposalId),
};
} else {
throw Error("payment failed");
}
return {
type: ConfirmPayResultType.Pending,
lastError: opRetry?.lastError,
transactionId: makeTransactionId(TransactionType.Payment, proposalId),
};
}
case OperationAttemptResultType.Pending:
logger.trace("reporting pending as confirmPay response");