commit 05428f8e53f24cac87b50f22a17d100f3ef9e242
parent b03fc2d6d9dff3a5bc2d74009aef0d9f0b7c9b67
Author: Marc Stibane <marc@taler.net>
Date: Sun, 1 Mar 2026 21:47:50 +0100
Error handling
Diffstat:
6 files changed, 51 insertions(+), 48 deletions(-)
diff --git a/TalerWallet1/Views/Actions/Banking/ManualWithdraw.swift b/TalerWallet1/Views/Actions/Banking/ManualWithdraw.swift
@@ -1,5 +1,5 @@
/*
- * This file is part of GNU Taler, ©2022-25 Taler Systems S.A.
+ * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
* See LICENSE.md
*/
/**
@@ -94,7 +94,7 @@ struct ManualWithdraw: View {
exchange: exchange)
} else { // should never happen, we either have an exchange or a balance
let title = "ManualWithdrawContent: Cannot determine scope" // should not happen, so no L10N
- ErrorView(title: title, message: nil, copyable: true) {
+ ErrorView(stack.push("ManualWithdraw"), title: title, message: nil, copyable: true) {
dismissTop(stack.push())
}
}
diff --git a/TalerWallet1/Views/Main/ErrorView.swift b/TalerWallet1/Views/Main/ErrorView.swift
@@ -1,5 +1,5 @@
/*
- * This file is part of GNU Taler, ©2022-25 Taler Systems S.A.
+ * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
* See LICENSE.md
*/
/**
@@ -14,20 +14,24 @@ enum ErrorData {
}
struct ErrorView: View {
+ let stack: CallStack
var title: String
var message: String? = nil
var copyable: Bool
var onDismiss: () -> Void
- init(title: String, message: String? = nil, copyable: Bool, onDismiss: @escaping () -> Void) {
+ init(_ stack: CallStack, title: String, message: String? = nil, copyable: Bool, onDismiss: @escaping () -> Void) {
+ self.stack = stack
self.title = title
self.message = message
self.copyable = copyable
self.onDismiss = onDismiss
}
- init(error: Error, devMode: Bool, onDismiss: @escaping () -> Void) {
+ init(_ stack: CallStack, error: Error, devMode: Bool, onDismiss: @escaping () -> Void) {
+ let internetError = String(localized: "Network problem")
+ let internetMessage = String(localized: "Please check your internet connection and try again.")
let walletCoreError = String(localized: "Internal core error")
let initializationError = String(localized: "Initialization error")
let serializationError = String(localized: "Serialization error")
@@ -35,36 +39,42 @@ struct ErrorView: View {
let unknownError = String(localized: "Unknown error")
switch error {
- case let walletError as WalletBackendError:
- switch walletError {
- case .walletCoreError(let error):
- if let json = error?.toJSON(), devMode {
- self.init(title: walletCoreError, message: json, copyable: true, onDismiss: onDismiss)
- } else if let hint = error?.errorResponse?.hint ?? error?.hint {
- self.init(title: walletCoreError, message: hint, copyable: false, onDismiss: onDismiss)
- } else if let message = error?.message {
- self.init(title: walletCoreError, message: message, copyable: false, onDismiss: onDismiss)
- } else {
- self.init(title: walletCoreError, copyable: false, onDismiss: onDismiss)
+ case let walletError as WalletBackendError:
+ switch walletError {
+ case .walletCoreError(let walletBackendResponseError):
+ if let responseError = walletBackendResponseError {
+ if responseError.code == 7001 {
+ self.init(stack, title: internetError, message: internetMessage, copyable: false, onDismiss: onDismiss)
+ break
+ }
+ }
+ if let json = walletBackendResponseError?.toJSON(), devMode {
+ self.init(stack, title: walletCoreError, message: json, copyable: true, onDismiss: onDismiss)
+ } else if let hint = walletBackendResponseError?.errorResponse?.hint ?? walletBackendResponseError?.hint {
+ self.init(stack, title: walletCoreError, message: hint, copyable: false, onDismiss: onDismiss)
+ } else if let message = walletBackendResponseError?.message {
+ self.init(stack, title: walletCoreError, message: message, copyable: false, onDismiss: onDismiss)
+ } else {
+ self.init(stack, title: walletCoreError, copyable: false, onDismiss: onDismiss)
+ }
+ case .initializationError:
+ self.init(stack, title: initializationError, copyable: false, onDismiss: onDismiss)
+ case .serializationError:
+ self.init(stack, title: serializationError, copyable: false, onDismiss: onDismiss)
+ case .deserializationError:
+ self.init(stack, title: deserializationError, copyable: false, onDismiss: onDismiss)
}
- case .initializationError:
- self.init(title: initializationError, copyable: false, onDismiss: onDismiss)
- case .serializationError:
- self.init(title: serializationError, copyable: false, onDismiss: onDismiss)
- case .deserializationError:
- self.init(title: deserializationError, copyable: false, onDismiss: onDismiss)
- }
- default:
- self.init(title: unknownError, message: error.localizedDescription, copyable: false, onDismiss: onDismiss)
+ default:
+ self.init(stack, title: unknownError, message: error.localizedDescription, copyable: false, onDismiss: onDismiss)
}
}
- init(data: ErrorData, devMode: Bool, onDismiss: @escaping () -> Void) {
+ init(_ stack: CallStack, data: ErrorData, devMode: Bool, onDismiss: @escaping () -> Void) {
switch data {
case .message(let title, let message):
- self.init(title: title, message: message, copyable: false, onDismiss: onDismiss)
+ self.init(stack, title: title, message: message, copyable: false, onDismiss: onDismiss)
case .error(let error):
- self.init(error: error, devMode: devMode, onDismiss: onDismiss)
+ self.init(stack, error: error, devMode: devMode, onDismiss: onDismiss)
}
}
@@ -111,15 +121,3 @@ struct ErrorView: View {
}
}
}
-
-struct ErrorSheet_Previews: PreviewProvider {
- static let error = WalletBackendError.walletCoreError(WalletBackendResponseError(
- code: 7025, when: Timestamp.now(),
- hint: "A KYC step is required before withdrawal can proceed",
- message: "A KYC step is required before withdrawal can proceed"))
-
- static var previews: some View {
- ErrorView(error: error, devMode: true, onDismiss: {})
- ErrorView(error: error, devMode: false, onDismiss: {})
- }
-}
diff --git a/TalerWallet1/Views/Main/MainView.swift b/TalerWallet1/Views/Main/MainView.swift
@@ -99,7 +99,7 @@ struct MainView: View {
if (!showScanner && urlToOpen == nil) {
if let error2 = model.error2 {
- ErrorView(data: error2, devMode: developerMode) {
+ ErrorView(stack.push("Main"), data: error2, devMode: developerMode) {
model.setError(nil)
}.interactiveDismissDisabled()
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
@@ -152,7 +152,8 @@ struct MainView: View {
// show launch animation until either ready or error
switch controller.backendState {
case .ready: mainContent
- case .error: ErrorView(title: "", // TODO: String(localized: ""),
+ case .error: ErrorView(stack.push("mainGroup"),
+ title: "", // TODO: String(localized: ""),
copyable: true) {}
default: LaunchAnimationView()
}
diff --git a/TalerWallet1/Views/Sheets/QRSheet.swift b/TalerWallet1/Views/Sheets/QRSheet.swift
@@ -1,5 +1,5 @@
/*
- * This file is part of GNU Taler, ©2022-25 Taler Systems S.A.
+ * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
* See LICENSE.md
*/
/**
@@ -50,7 +50,8 @@ struct QRSheet: View {
urlToOpen: $urlToOpen) // !!! will set @Binding to nil
} else {
// let _ = print(scannedURL) // TODO: error logging
- ErrorView(title: String(localized: "Scanned QR is no talerURI"),
+ ErrorView(stack.push(),
+ title: String(localized: "Scanned QR is no talerURI"),
message: scannedURL.absoluteString,
copyable: true) {
scannedSomething = false
@@ -58,9 +59,11 @@ struct QRSheet: View {
}
}
} else {
- ErrorView(title: String(localized: "Scanned QR is no URL"),
+ ErrorView(stack.push(),
+ title: String(localized: "Scanned QR is no URL"),
message: scannedCode,
- copyable: true) {
+ copyable: true
+ ) {
scannedSomething = false
dismissTop(stack.push())
}
diff --git a/TalerWallet1/Views/Sheets/Sheet.swift b/TalerWallet1/Views/Sheets/Sheet.swift
@@ -56,7 +56,7 @@ struct Sheet: View {
.accessibilityValue(idString)
}
if let error2 = model.error2 {
- ErrorView(data: error2, devMode: developerMode) {
+ ErrorView(stack.push(), data: error2, devMode: developerMode) {
model.setError(nil)
logger.log("ErrorSheet dismissTop")
dismissTop(stack.push())
diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
@@ -416,7 +416,8 @@ struct TransactionSummaryV: View {
badge: CONFIRM_BANK)
} } } }
@unknown default:
- ErrorView(title: "Unknown withdrawal type", // should not happen, so no L10N
+ ErrorView(stack.push(),
+ title: "Unknown withdrawal type", // should not happen, so no L10N
message: withdrawalDetails.type.rawValue,
copyable: true) {
dismissTop(stack.push())