diff --git a/composeApp/src/commonMain/kotlin/com/example/casera/util/ErrorMessageParser.kt b/composeApp/src/commonMain/kotlin/com/example/casera/util/ErrorMessageParser.kt index 4999b17..7aea3fa 100644 --- a/composeApp/src/commonMain/kotlin/com/example/casera/util/ErrorMessageParser.kt +++ b/composeApp/src/commonMain/kotlin/com/example/casera/util/ErrorMessageParser.kt @@ -9,23 +9,58 @@ import kotlinx.serialization.json.jsonPrimitive */ object ErrorMessageParser { + // Network/connection error patterns to detect + private val networkErrorPatterns = listOf( + "Could not connect to the server" to "Unable to connect to the server. Please check your internet connection.", + "NSURLErrorDomain" to "Unable to connect to the server. Please check your internet connection.", + "UnresolvedAddressException" to "Unable to connect to the server. Please check your internet connection.", + "ConnectException" to "Unable to connect to the server. Please check your internet connection.", + "SocketTimeoutException" to "Request timed out. Please try again.", + "TimeoutException" to "Request timed out. Please try again.", + "No address associated" to "Unable to connect to the server. Please check your internet connection.", + "Network is unreachable" to "No internet connection. Please check your network settings.", + "Connection refused" to "Unable to connect to the server. The server may be down.", + "Connection reset" to "Connection was interrupted. Please try again.", + "SSLHandshakeException" to "Secure connection failed. Please try again.", + "CertificateException" to "Secure connection failed. Please try again.", + "UnknownHostException" to "Unable to connect to the server. Please check your internet connection.", + "java.net.SocketException" to "Connection error. Please try again.", + "CFNetwork" to "Unable to connect to the server. Please check your internet connection.", + "kCFStreamError" to "Unable to connect to the server. Please check your internet connection.", + "Code=-1004" to "Unable to connect to the server. Please check your internet connection.", + "Code=-1009" to "No internet connection. Please check your network settings.", + "Code=-1001" to "Request timed out. Please try again." + ) + /** * Parses error messages to extract user-friendly text - * If the error message is JSON, extract relevant error details - * @param rawMessage The raw error message from the API + * Handles network errors, JSON error responses, and raw error messages + * @param rawMessage The raw error message from the API or exception * @return A user-friendly error message */ fun parse(rawMessage: String): String { val trimmed = rawMessage.trim() - // Check if the message looks like JSON (starts with { or [) - if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) { - // Not JSON, return as-is - return rawMessage + // Check for network/connection errors first (these are technical messages from exceptions) + for ((pattern, friendlyMessage) in networkErrorPatterns) { + if (trimmed.contains(pattern, ignoreCase = true)) { + return friendlyMessage + } } - // If it's JSON, it's not meant for user display - // Try to parse and extract meaningful error info + // Check if it looks like a technical exception message + if (isTechnicalError(trimmed)) { + return "Something went wrong. Please try again." + } + + // Check if the message looks like JSON (starts with { or [) + if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) { + // Not JSON - if it's a short, readable message, return it + // Otherwise return a generic message + return if (isUserFriendly(trimmed)) trimmed else "Something went wrong. Please try again." + } + + // If it's JSON, try to parse and extract meaningful error info return try { val jsonElement = Json.parseToJsonElement(trimmed) @@ -51,4 +86,37 @@ object ErrorMessageParser { "An error occurred. Please try again." } } + + /** + * Checks if the message looks like a technical/developer error (stack trace, exception, etc) + */ + private fun isTechnicalError(message: String): Boolean { + val technicalIndicators = listOf( + "Exception", + "Error Domain=", + "UserInfo=", + "at com.", + "at org.", + "at java.", + "at kotlin.", + "at io.", + "Caused by:", + "Stack trace:", + ".kt:", + ".java:", + "0x", + "Code=", + "interface:", + "LocalDataTask" + ) + return technicalIndicators.any { message.contains(it, ignoreCase = true) } + } + + /** + * Checks if a message is user-friendly (short, no technical jargon) + */ + private fun isUserFriendly(message: String): Boolean { + // If it's short and doesn't contain technical indicators, it's probably user-friendly + return message.length < 200 && !isTechnicalError(message) + } } diff --git a/iosApp/iosApp/Contractor/ContractorSharingManager.swift b/iosApp/iosApp/Contractor/ContractorSharingManager.swift index ebb26b5..087d7dd 100644 --- a/iosApp/iosApp/Contractor/ContractorSharingManager.swift +++ b/iosApp/iosApp/Contractor/ContractorSharingManager.swift @@ -126,7 +126,7 @@ class ContractorSharingManager: ObservableObject { completion(false) } } catch { - self.importError = error.localizedDescription + self.importError = ErrorMessageParser.parse(error.localizedDescription) self.isImporting = false completion(false) } diff --git a/iosApp/iosApp/Contractor/ContractorViewModel.swift b/iosApp/iosApp/Contractor/ContractorViewModel.swift index 445a010..9fd2c56 100644 --- a/iosApp/iosApp/Contractor/ContractorViewModel.swift +++ b/iosApp/iosApp/Contractor/ContractorViewModel.swift @@ -57,7 +57,7 @@ class ContractorViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -79,7 +79,7 @@ class ContractorViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -104,7 +104,7 @@ class ContractorViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isCreating = false completion(false) } @@ -130,7 +130,7 @@ class ContractorViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isUpdating = false completion(false) } @@ -156,7 +156,7 @@ class ContractorViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isDeleting = false completion(false) } @@ -176,7 +176,7 @@ class ContractorViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } diff --git a/iosApp/iosApp/Documents/DocumentViewModel.swift b/iosApp/iosApp/Documents/DocumentViewModel.swift index 16cce2f..ed99a68 100644 --- a/iosApp/iosApp/Documents/DocumentViewModel.swift +++ b/iosApp/iosApp/Documents/DocumentViewModel.swift @@ -61,7 +61,7 @@ class DocumentViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -135,7 +135,7 @@ class DocumentViewModel: ObservableObject { completion(false, self.errorMessage) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false completion(false, self.errorMessage) } @@ -203,7 +203,7 @@ class DocumentViewModel: ObservableObject { completion(false, self.errorMessage) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false completion(false, self.errorMessage) } @@ -228,7 +228,7 @@ class DocumentViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false completion(false) } diff --git a/iosApp/iosApp/Helpers/ErrorMessageParser.swift b/iosApp/iosApp/Helpers/ErrorMessageParser.swift index 1f894e6..4090982 100644 --- a/iosApp/iosApp/Helpers/ErrorMessageParser.swift +++ b/iosApp/iosApp/Helpers/ErrorMessageParser.swift @@ -1,22 +1,82 @@ import Foundation -/// Utility for parsing and cleaning error messages from API responses +/// Utility for parsing and cleaning error messages from API responses and network errors enum ErrorMessageParser { + // Network/connection error patterns to detect + private static let networkErrorPatterns: [(pattern: String, message: String)] = [ + ("Could not connect to the server", "Unable to connect to the server. Please check your internet connection."), + ("NSURLErrorDomain", "Unable to connect to the server. Please check your internet connection."), + ("The Internet connection appears to be offline", "No internet connection. Please check your network settings."), + ("A server with the specified hostname could not be found", "Unable to connect to the server. Please check your internet connection."), + ("The request timed out", "Request timed out. Please try again."), + ("The network connection was lost", "Connection was interrupted. Please try again."), + ("An SSL error has occurred", "Secure connection failed. Please try again."), + ("CFNetwork", "Unable to connect to the server. Please check your internet connection."), + ("kCFStreamError", "Unable to connect to the server. Please check your internet connection."), + ("Code=-1004", "Unable to connect to the server. Please check your internet connection."), + ("Code=-1009", "No internet connection. Please check your network settings."), + ("Code=-1001", "Request timed out. Please try again."), + ("Code=-1003", "Unable to connect to the server. Please check your internet connection."), + ("Code=-1005", "Connection was interrupted. Please try again."), + ("Code=-1200", "Secure connection failed. Please try again."), + ("UnresolvedAddressException", "Unable to connect to the server. Please check your internet connection."), + ("ConnectException", "Unable to connect to the server. Please check your internet connection."), + ("SocketTimeoutException", "Request timed out. Please try again."), + ("Connection refused", "Unable to connect to the server. The server may be down."), + ("Connection reset", "Connection was interrupted. Please try again.") + ] + + // Indicators that a message is technical/developer-facing + private static let technicalIndicators = [ + "Exception", + "Error Domain=", + "UserInfo=", + "at com.", + "at org.", + "at java.", + "at kotlin.", + "at io.", + "Caused by:", + "Stack trace:", + ".kt:", + ".java:", + ".swift:", + "0x", + "Code=", + "interface:", + "LocalDataTask", + "NSUnderlyingError", + "_kCF" + ] + /// Parses error messages to extract user-friendly text - /// If the error message is JSON, extract relevant error details - /// - Parameter rawMessage: The raw error message from the API + /// Handles network errors, JSON error responses, and raw error messages + /// - Parameter rawMessage: The raw error message from the API or exception /// - Returns: A user-friendly error message static func parse(_ rawMessage: String) -> String { - // Check if the message looks like JSON (starts with { or [) let trimmed = rawMessage.trimmingCharacters(in: .whitespacesAndNewlines) - guard trimmed.hasPrefix("{") || trimmed.hasPrefix("[") else { - // Not JSON, return as-is - return rawMessage + + // Check for network/connection errors first (these are technical messages from exceptions) + for (pattern, friendlyMessage) in networkErrorPatterns { + if trimmed.localizedCaseInsensitiveContains(pattern) { + return friendlyMessage + } } - // If it's JSON, it's not meant for user display - // Try to parse and extract meaningful error info + // Check if it looks like a technical exception message + if isTechnicalError(trimmed) { + return "Something went wrong. Please try again." + } + + // Check if the message looks like JSON (starts with { or [) + guard trimmed.hasPrefix("{") || trimmed.hasPrefix("[") else { + // Not JSON - if it's a short, readable message, return it + // Otherwise return a generic message + return isUserFriendly(trimmed) ? trimmed : "Something went wrong. Please try again." + } + + // If it's JSON, try to parse and extract meaningful error info guard let data = trimmed.data(using: .utf8) else { return "An error occurred. Please try again." } @@ -47,4 +107,15 @@ enum ErrorMessageParser { // If we couldn't parse or extract a message, return a generic error return "An error occurred. Please try again." } + + /// Checks if the message looks like a technical/developer error (stack trace, exception, etc) + private static func isTechnicalError(_ message: String) -> Bool { + return technicalIndicators.contains { message.localizedCaseInsensitiveContains($0) } + } + + /// Checks if a message is user-friendly (short, no technical jargon) + private static func isUserFriendly(_ message: String) -> Bool { + // If it's short and doesn't contain technical indicators, it's probably user-friendly + return message.count < 200 && !isTechnicalError(message) + } } diff --git a/iosApp/iosApp/Login/AppleSignInViewModel.swift b/iosApp/iosApp/Login/AppleSignInViewModel.swift index 63bcf19..bf818e4 100644 --- a/iosApp/iosApp/Login/AppleSignInViewModel.swift +++ b/iosApp/iosApp/Login/AppleSignInViewModel.swift @@ -65,7 +65,7 @@ class AppleSignInViewModel: ObservableObject { } } catch { self.isLoading = false - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } @@ -115,7 +115,7 @@ class AppleSignInViewModel: ObservableObject { } errorMessage = appleError.errorDescription } else { - errorMessage = error.localizedDescription + errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } diff --git a/iosApp/iosApp/Login/LoginView.swift b/iosApp/iosApp/Login/LoginView.swift index 8e8a0a0..d0420fa 100644 --- a/iosApp/iosApp/Login/LoginView.swift +++ b/iosApp/iosApp/Login/LoginView.swift @@ -352,10 +352,6 @@ struct LoginView: View { showPasswordReset = true } } - .handleErrors( - error: viewModel.errorMessage, - onRetry: { viewModel.login() } - ) } } diff --git a/iosApp/iosApp/Login/LoginViewModel.swift b/iosApp/iosApp/Login/LoginViewModel.swift index 9d74e82..021ea8b 100644 --- a/iosApp/iosApp/Login/LoginViewModel.swift +++ b/iosApp/iosApp/Login/LoginViewModel.swift @@ -97,7 +97,7 @@ class LoginViewModel: ObservableObject { } } catch { self.isLoading = false - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } diff --git a/iosApp/iosApp/PasswordReset/PasswordResetViewModel.swift b/iosApp/iosApp/PasswordReset/PasswordResetViewModel.swift index a093c22..9f43f12 100644 --- a/iosApp/iosApp/PasswordReset/PasswordResetViewModel.swift +++ b/iosApp/iosApp/PasswordReset/PasswordResetViewModel.swift @@ -69,7 +69,7 @@ class PasswordResetViewModel: ObservableObject { } } catch { self.isLoading = false - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } @@ -106,7 +106,7 @@ class PasswordResetViewModel: ObservableObject { } } catch { self.isLoading = false - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } @@ -155,7 +155,7 @@ class PasswordResetViewModel: ObservableObject { } } catch { self.isLoading = false - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } diff --git a/iosApp/iosApp/Profile/NotificationPreferencesView.swift b/iosApp/iosApp/Profile/NotificationPreferencesView.swift index 6753a9c..8a3266e 100644 --- a/iosApp/iosApp/Profile/NotificationPreferencesView.swift +++ b/iosApp/iosApp/Profile/NotificationPreferencesView.swift @@ -382,7 +382,7 @@ class NotificationPreferencesViewModelWrapper: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -435,7 +435,7 @@ class NotificationPreferencesViewModelWrapper: ObservableObject { self.isSaving = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isSaving = false } } diff --git a/iosApp/iosApp/Profile/ProfileViewModel.swift b/iosApp/iosApp/Profile/ProfileViewModel.swift index a883849..2bbf0c1 100644 --- a/iosApp/iosApp/Profile/ProfileViewModel.swift +++ b/iosApp/iosApp/Profile/ProfileViewModel.swift @@ -71,7 +71,7 @@ class ProfileViewModel: ObservableObject { self.isLoadingUser = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoadingUser = false } } @@ -113,7 +113,7 @@ class ProfileViewModel: ObservableObject { } } catch { self.isLoading = false - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.successMessage = nil } } diff --git a/iosApp/iosApp/Register/RegisterViewModel.swift b/iosApp/iosApp/Register/RegisterViewModel.swift index d70e126..4346e1a 100644 --- a/iosApp/iosApp/Register/RegisterViewModel.swift +++ b/iosApp/iosApp/Register/RegisterViewModel.swift @@ -76,7 +76,7 @@ class RegisterViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } diff --git a/iosApp/iosApp/Residence/ManageUsersView.swift b/iosApp/iosApp/Residence/ManageUsersView.swift index cdc45a6..90b789e 100644 --- a/iosApp/iosApp/Residence/ManageUsersView.swift +++ b/iosApp/iosApp/Residence/ManageUsersView.swift @@ -112,7 +112,7 @@ struct ManageUsersView: View { } } catch { await MainActor.run { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -162,7 +162,7 @@ struct ManageUsersView: View { } } catch { await MainActor.run { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isGeneratingCode = false } } @@ -188,7 +188,7 @@ struct ManageUsersView: View { } } catch { await MainActor.run { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } diff --git a/iosApp/iosApp/Residence/ResidenceDetailView.swift b/iosApp/iosApp/Residence/ResidenceDetailView.swift index 3e5bc16..6bfc656 100644 --- a/iosApp/iosApp/Residence/ResidenceDetailView.swift +++ b/iosApp/iosApp/Residence/ResidenceDetailView.swift @@ -468,7 +468,7 @@ private extension ResidenceDetailView { } catch { await MainActor.run { self.isDeleting = false - self.viewModel.errorMessage = error.localizedDescription + self.viewModel.errorMessage = ErrorMessageParser.parse(error.localizedDescription) } } } @@ -500,7 +500,7 @@ private extension ResidenceDetailView { } } catch { await MainActor.run { - self.contractorsError = error.localizedDescription + self.contractorsError = ErrorMessageParser.parse(error.localizedDescription) self.isLoadingContractors = false } } diff --git a/iosApp/iosApp/Residence/ResidenceSharingManager.swift b/iosApp/iosApp/Residence/ResidenceSharingManager.swift index 91bcdad..3dfcfb5 100644 --- a/iosApp/iosApp/Residence/ResidenceSharingManager.swift +++ b/iosApp/iosApp/Residence/ResidenceSharingManager.swift @@ -151,7 +151,7 @@ class ResidenceSharingManager: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isImporting = false completion(false) } diff --git a/iosApp/iosApp/Residence/ResidenceViewModel.swift b/iosApp/iosApp/Residence/ResidenceViewModel.swift index 5baea4d..9b67158 100644 --- a/iosApp/iosApp/Residence/ResidenceViewModel.swift +++ b/iosApp/iosApp/Residence/ResidenceViewModel.swift @@ -75,7 +75,7 @@ class ResidenceViewModel: ObservableObject { } self.isLoading = false } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -105,7 +105,7 @@ class ResidenceViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -127,7 +127,7 @@ class ResidenceViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } } @@ -176,7 +176,7 @@ class ResidenceViewModel: ObservableObject { } catch { print("🏠 ResidenceVM: Exception: \(error)") await MainActor.run { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false completion(nil) } @@ -205,7 +205,7 @@ class ResidenceViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false completion(false) } @@ -228,7 +228,7 @@ class ResidenceViewModel: ObservableObject { self.isGeneratingReport = false } } catch { - self.reportMessage = error.localizedDescription + self.reportMessage = ErrorMessageParser.parse(error.localizedDescription) self.isGeneratingReport = false } } @@ -263,7 +263,7 @@ class ResidenceViewModel: ObservableObject { completion(false) } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false completion(false) } diff --git a/iosApp/iosApp/Task/TaskViewModel.swift b/iosApp/iosApp/Task/TaskViewModel.swift index 6ccc7ca..4b3f986 100644 --- a/iosApp/iosApp/Task/TaskViewModel.swift +++ b/iosApp/iosApp/Task/TaskViewModel.swift @@ -85,7 +85,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.create, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -112,7 +112,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.cancel, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -136,7 +136,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.uncancel, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -160,7 +160,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.markInProgress, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -184,7 +184,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.archive, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -208,7 +208,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.unarchive, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -232,7 +232,7 @@ class TaskViewModel: ObservableObject { } } catch { self.actionState = .error(.update, error.localizedDescription) - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) completion(false) } } @@ -268,7 +268,7 @@ class TaskViewModel: ObservableObject { self.isLoadingCompletions = false } } catch { - self.completionsError = error.localizedDescription + self.completionsError = ErrorMessageParser.parse(error.localizedDescription) self.isLoadingCompletions = false } } @@ -360,7 +360,7 @@ class TaskViewModel: ObservableObject { } } catch { await MainActor.run { - self.tasksError = error.localizedDescription + self.tasksError = ErrorMessageParser.parse(error.localizedDescription) self.isLoadingTasks = false } } diff --git a/iosApp/iosApp/VerifyEmail/VerifyEmailViewModel.swift b/iosApp/iosApp/VerifyEmail/VerifyEmailViewModel.swift index f97f18a..6309ae9 100644 --- a/iosApp/iosApp/VerifyEmail/VerifyEmailViewModel.swift +++ b/iosApp/iosApp/VerifyEmail/VerifyEmailViewModel.swift @@ -57,7 +57,7 @@ class VerifyEmailViewModel: ObservableObject { self.isLoading = false } } catch { - self.errorMessage = error.localizedDescription + self.errorMessage = ErrorMessageParser.parse(error.localizedDescription) self.isLoading = false } }