swiftui-multiplatform/Shared/ErrorHandling/ErrorConstants.swift
Angelo Stavrow a51bbd3abc
Alert on error: shared code (#207)
* Initial work on presenting alert on error

* Move Account-related error handling up the hierarchy

* Handle errors on logout

* Fix for temporary debugging

* Clean up WriteFreelyModel’s published vars

* Add error handling to top-level content view

* Set current error on API call failures

* Set current error on API call handlers

* Move User Defaults errors to ErrorConstants file

* Add default values for some error strings

* Handle purging post errors

* Add FIXME to track silent failure on fetching collections

As collections are fetched and added to the `list` property in the CollectionListModel’s initializer, it’s tricky to throw an error here: we call it as a property initializer in CollectionListView, which cannot throw.

Consider refactoring this logic such that we’re using, for example, a @FetchRequest in CollectionListView instead.

* Handle errors in (most) shared code

Two outliers to come back to are:

- the LocalStoreManager, where we can’t set a current error in the WriteFreelyModel in methods that can’t throw
- the CollectionListModel, where the initializer can’t throw because we use it as a property initializer in CollectionListView

* Add error handling to Mac app

* Revert "Add error handling to Mac app"

This reverts commit b1a8b8b29c.
2022-07-27 09:56:32 -04:00

174 lines
6.2 KiB
Swift

import Foundation
// MARK: - Network Errors
enum NetworkError: Error {
case noConnectionError
}
extension NetworkError: LocalizedError {
public var errorDescription: String? {
switch self {
case .noConnectionError:
return NSLocalizedString(
"There is no internet connection at the moment. Please reconnect or try again later.",
comment: ""
)
}
}
}
// MARK: - Keychain Errors
enum KeychainError: Error {
case couldNotStoreAccessToken
case couldNotPurgeAccessToken
case couldNotFetchAccessToken
}
extension KeychainError: LocalizedError {
public var errorDescription: String? {
switch self {
case .couldNotStoreAccessToken:
return NSLocalizedString("There was a problem storing your access token in the Keychain.", comment: "")
case .couldNotPurgeAccessToken:
return NSLocalizedString("Something went wrong purging the token from the Keychain.", comment: "")
case .couldNotFetchAccessToken:
return NSLocalizedString("Something went wrong fetching the token from the Keychain.", comment: "")
}
}
}
// MARK: - Account Errors
enum AccountError: Error {
case invalidPassword
case usernameNotFound
case serverNotFound
case invalidServerURL
case unknownLoginError
case genericAuthError
}
extension AccountError: LocalizedError {
public var errorDescription: String? {
switch self {
case .serverNotFound:
return NSLocalizedString(
"The server could not be found. Please check the information you've entered and try again.",
comment: ""
)
case .invalidPassword:
return NSLocalizedString(
"Invalid password. Please check that you've entered your password correctly and try logging in again.",
comment: ""
)
case .usernameNotFound:
return NSLocalizedString(
"Username not found. Did you use your email address by mistake?",
comment: ""
)
case .invalidServerURL:
return NSLocalizedString(
"Please enter a valid instance domain name. It should look like \"https://example.com\" or \"write.as\".", // swiftlint:disable:this line_length
comment: ""
)
case .genericAuthError:
return NSLocalizedString("Something went wrong, please try logging in again.", comment: "")
case .unknownLoginError:
return NSLocalizedString("An unknown error occurred while trying to login.", comment: "")
}
}
}
// MARK: - User Defaults Errors
enum UserDefaultsError: Error {
case couldNotMigrateStandardDefaults
}
extension UserDefaultsError: LocalizedError {
public var errorDescription: String? {
switch self {
case .couldNotMigrateStandardDefaults:
return NSLocalizedString("Could not migrate user defaults to group container", comment: "")
}
}
}
// MARK: - Local Store Errors
enum LocalStoreError: Error {
case couldNotSaveContext
case couldNotFetchCollections
case couldNotFetchPosts(String = "")
case couldNotPurgePosts(String = "")
case couldNotPurgeCollections
case couldNotLoadStore(String)
case couldNotMigrateStore(String)
case couldNotDeleteStoreAfterMigration(String)
case genericError(String = "")
}
extension LocalStoreError: LocalizedError {
public var errorDescription: String? {
switch self {
case .couldNotSaveContext:
return NSLocalizedString("Error saving context", comment: "")
case .couldNotFetchCollections:
return NSLocalizedString("Failed to fetch blogs from local store.", comment: "")
case .couldNotFetchPosts(let postFilter):
if postFilter.isEmpty {
return NSLocalizedString("Failed to fetch posts from local store.", comment: "")
} else {
return NSLocalizedString("Failed to fetch \(postFilter) posts from local store.", comment: "")
}
case .couldNotPurgePosts(let postFilter):
if postFilter.isEmpty {
return NSLocalizedString("Failed to purge \(postFilter) posts from local store.", comment: "")
} else {
return NSLocalizedString("Failed to purge posts from local store.", comment: "")
}
case .couldNotPurgeCollections:
return NSLocalizedString("Failed to purge cached collections", comment: "")
case .couldNotLoadStore(let errorDescription):
return NSLocalizedString("Something went wrong loading local store: \(errorDescription)", comment: "")
case .couldNotMigrateStore(let errorDescription):
return NSLocalizedString("Something went wrong migrating local store: \(errorDescription)", comment: "")
case .couldNotDeleteStoreAfterMigration(let errorDescription):
return NSLocalizedString("Something went wrong deleting old store: \(errorDescription)", comment: "")
case .genericError(let customContent):
if customContent.isEmpty {
return NSLocalizedString("Something went wrong accessing device storage", comment: "")
} else {
return NSLocalizedString(customContent, comment: "")
}
}
}
}
// MARK: - Application Errors
enum AppError: Error {
case couldNotGetLoggedInClient
case couldNotGetPostId
case genericError(String = "")
}
extension AppError: LocalizedError {
public var errorDescription: String? {
switch self {
case .couldNotGetLoggedInClient:
return NSLocalizedString("Something went wrong trying to access the WriteFreely client.", comment: "")
case .couldNotGetPostId:
return NSLocalizedString("Something went wrong trying to get the post's unique ID.", comment: "")
case .genericError(let customContent):
if customContent.isEmpty {
return NSLocalizedString("Something went wrong", comment: "")
} else {
return NSLocalizedString(customContent, comment: "")
}
}
}
}