taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit 6d3c1693bed9a99672b58622ac5d4b550058a910
parent 723f07a88112160a3819ed8f6976c5e6b0dcb5c9
Author: Marc Stibane <marc@taler.net>
Date:   Tue, 18 Feb 2025 21:44:18 +0100

Errors

Diffstat:
MTalerWallet1/Backend/WalletBackendError.swift | 62+++++++++-----------------------------------------------------
MTalerWallet1/Model/Model+Exchange.swift | 2+-
MTalerWallet1/Model/Transaction.swift | 4++--
MTalerWallet1/Model/WalletModel.swift | 67++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 74 insertions(+), 61 deletions(-)

diff --git a/TalerWallet1/Backend/WalletBackendError.swift b/TalerWallet1/Backend/WalletBackendError.swift @@ -18,66 +18,22 @@ enum WalletBackendError: Error { case walletCoreError(WalletBackendResponseError?) } -struct ErrorResponse: Codable { - var code: Int - /// English description of the error code. - var hint: String - - /// Error details, type depends on `talerErrorCode`. - var detail: String? = nil -} - - -struct InsufficientBalanceDetailsPerExchange: Codable { - var balanceAvailable: Amount - var balanceMaterial: Amount - var balanceExchangeDepositable: Amount - var balanceAgeAcceptable: Amount - var balanceReceiverAcceptable: Amount - var balanceReceiverDepositable: Amount - var maxEffectiveSpendAmount: Amount - /// Exchange doesn't have global fees configured for the relevant year, p2p payments aren't possible. - var missingGlobalFees: Bool -} - -/// Detailed reason for why the wallet's balance is insufficient. -struct PaymentInsufficientBalanceDetails: Codable { - /// Amount requested by the merchant. - var amountRequested: Amount - /// Balance of type "available" (see balance.ts for definition). - var balanceAvailable: Amount - /// Balance of type "material" (see balance.ts for definition). - var balanceMaterial: Amount - /// Balance of type "age-acceptable" (see balance.ts for definition). - var balanceAgeAcceptable: Amount - /// Balance of type "merchant-acceptable" (see balance.ts for definition). - var balanceReceiverAcceptable: Amount - /// Balance of type ... - var balanceReceiverDepositable: Amount - var balanceExchangeDepositable: Amount - /// Maximum effective amount that the wallet can spend, when all fees are paid by the wallet. - var maxEffectiveSpendAmount: Amount - var perExchange: [String : InsufficientBalanceDetailsPerExchange] -} - /// Information supplied by the backend describing an error. struct WalletBackendResponseError: Codable { - /// Numeric error code defined defined in the GANA gnu-taler-error-codes registry. + /// Numeric error code defined below (-1..-4) var code: Int - + // all other fields are optional: var when: Timestamp? - /// English description of the error code. - var hint: String - - var requestUrl: String? = nil - - var httpStatusCode: Int? = nil + var hint: String? + /// English diagnostic message that can give details for the instance of the error. + var message: String? - var errorResponse: ErrorResponse? = nil +// var requestUrl: String? +// var httpStatusCode: Int? +// var requestMethod: String? - /// English diagnostic message that can give details for the instance of the error. - var message: String? = nil + var errorResponse: TalerErrorDetail? var insufficientBalanceDetails: PaymentInsufficientBalanceDetails? = nil } diff --git a/TalerWallet1/Model/Model+Exchange.swift b/TalerWallet1/Model/Model+Exchange.swift @@ -13,7 +13,7 @@ import SymLog fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for debugging struct ExchangeError: Codable, Hashable { - var error: HTTPError + var error: TalerErrorDetail } enum ExchangeEntryStatus: String, Codable { diff --git a/TalerWallet1/Model/Transaction.swift b/TalerWallet1/Model/Transaction.swift @@ -514,8 +514,8 @@ struct RefreshError: Decodable { var when: Timestamp var hint: String var stack: String? - var numErrors: Int? // how many coins had errors - var errors: [HTTPError]? // 1..max(5, numErrors) + var numErrors: Int? // how many coins had errors + var errors: [TalerErrorDetail]? // 1..max(5, numErrors) } struct RefreshTransactionDetails: Decodable { var refreshReason: RefreshReason diff --git a/TalerWallet1/Model/WalletModel.swift b/TalerWallet1/Model/WalletModel.swift @@ -12,20 +12,77 @@ import os.log fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for debugging +enum InsufficientBalanceHint: String, Codable { + /// Merchant doesn't accept money from exchange(s) that the wallet supports + case merchantAcceptInsufficient = "merchant-accept-insufficient" + /// Merchant accepts funds from a matching exchange, but the funds can't be deposited with the wire method + case merchantDepositInsufficient = "merchant-deposit-insufficient" + /// While in principle the balance is sufficient, the age restriction on coins causes the spendable balance to be insufficient + case ageRestricted = "age-restricted" + /// Wallet has enough available funds, but the material funds are insufficient + /// Usually because there is a pending refresh operation + case walletBalanceMaterialInsufficient = "wallet-balance-material-insufficient" + /// The wallet simply doesn't have enough available funds + case walletBalanceAvailableInsufficient = "wallet-balance-available-insufficient" + /// Exchange is missing the global fee configuration, thus fees are unknown + /// and funds from this exchange can't be used for p2p payments + case exchangeMissingGlobalFees = "exchange-missing-global-fees" + /// Even though the balance looks sufficient for the instructed amount, + /// the fees can be covered by neither the merchant nor the remaining wallet balance + case feesNotCovered = "fees-not-covered" +} + +struct InsufficientBalanceDetailsPerExchange: Codable, Hashable { + var balanceAvailable: Amount + var balanceMaterial: Amount + var balanceExchangeDepositable: Amount + var balanceAgeAcceptable: Amount + var balanceReceiverAcceptable: Amount + var balanceReceiverDepositable: Amount + var maxEffectiveSpendAmount: Amount + /// Exchange doesn't have global fees configured for the relevant year, p2p payments aren't possible. + var missingGlobalFees: Bool +} + +/// Detailed reason for why the wallet's balance is insufficient. +struct PaymentInsufficientBalanceDetails: Codable, Hashable { + /// Amount requested by the merchant. + var amountRequested: Amount + var causeHint: InsufficientBalanceHint? + /// Balance of type "available" (see balance.ts for definition). + var balanceAvailable: Amount + /// Balance of type "material" (see balance.ts for definition). + var balanceMaterial: Amount + /// Balance of type "age-acceptable" (see balance.ts for definition). + var balanceAgeAcceptable: Amount + /// Balance of type "merchant-acceptable" (see balance.ts for definition). + var balanceReceiverAcceptable: Amount + /// Balance of type ... + var balanceReceiverDepositable: Amount + var balanceExchangeDepositable: Amount + /// Maximum effective amount that the wallet can spend, when all fees are paid by the wallet. + var maxEffectiveSpendAmount: Amount + var perExchange: [String : InsufficientBalanceDetailsPerExchange] +} +// MARK: - struct TalerErrorDetail: Codable, Hashable { + /// Numeric error code defined in the GANA gnu-taler-error-codes registry. var code: Int + // all other fields are optional: var when: Timestamp? + /// English description of the error code. var hint: String? -} -struct HTTPError: Codable, Hashable { - var code: Int + /// Error details, type depends on `talerErrorCode`. + var detail: String? + + /// HTTPError var requestUrl: String? - var hint: String var requestMethod: String? var httpStatusCode: Int? - var when: Timestamp? var stack: String? + + var insufficientBalanceDetails: PaymentInsufficientBalanceDetails? } // MARK: - /// Communicate with wallet-core