diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2022-02-17 13:18:19 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2022-02-22 11:24:14 +0100 |
| commit | 2923b851ec06c9823171559c3f4334bcca22f6ae (patch) | |
| tree | f3ceee0bdfe9647b2663bfeaa7e48b8ff2179fba | |
| parent | 143a58a5b5dd5419be8bd84569c571603ecd73a8 (diff) | |
| download | mullvadvpn-2923b851ec06c9823171559c3f4334bcca22f6ae.tar.xz mullvadvpn-2923b851ec06c9823171559c3f4334bcca22f6ae.zip | |
Add CustomChainedErrorDescriptionProtocol
| -rw-r--r-- | ios/MullvadVPN/ChainedError.swift | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/ios/MullvadVPN/ChainedError.swift b/ios/MullvadVPN/ChainedError.swift index 86977609a1..446ed99469 100644 --- a/ios/MullvadVPN/ChainedError.swift +++ b/ios/MullvadVPN/ChainedError.swift @@ -8,26 +8,19 @@ import Foundation -/// A protocol describing errors that can be chained together +/// A protocol describing errors that can be chained together. protocol ChainedError: LocalizedError { - /// A source error when available + /// A source error when available. var source: Error? { get } } -final class AnyChainedError: ChainedError { - private let wrappedError: Error - - init(_ error: Error) { - wrappedError = error - } - - var errorDescription: String? { - return wrappedError.localizedDescription - } +/// A protocol providing error a way to override error description when printing error chain. +protocol CustomChainedErrorDescriptionProtocol { + /// A custom error description that overrides `localizedDescription` when printing error chain. + var customErrorDescription: String? { get } } extension ChainedError { - var source: Error? { let reflection = Mirror(reflecting: self) @@ -42,14 +35,20 @@ extension ChainedError { return nil } - /// Creates a string representation of the entire error chain. - /// An extra `message` is added at the start of the chain when given + /// Create a string representation of the entire error chain. + /// An extra `message` is added at the start of the chain when given. func displayChain(message: String? = nil) -> String { - var s = message.map { "Error: \($0)\nCaused by: \(self.localizedDescription)" } - ?? "Error: \(self.localizedDescription)" + var s: String + + let errorDescription = Self.getErrorDescription(self) + if let message = message { + s = "Error: \(message)\nCaused by: \(errorDescription)" + } else { + s = "Error: \(errorDescription)" + } for sourceError in makeChainIterator() { - s.append("\nCaused by: \(sourceError.localizedDescription)") + s.append("\nCaused by: \(Self.getErrorDescription(sourceError))") } return s @@ -62,4 +61,38 @@ extension ChainedError { return current } } + + private static func getErrorDescription(_ error: Error) -> String { + let anError = error as? CustomChainedErrorDescriptionProtocol + + return anError?.customErrorDescription ?? error.localizedDescription + } +} + +extension CustomChainedErrorDescriptionProtocol { + var customErrorDescription: String? { + return nil + } +} + +/// A type-erasing container type for any `Error` that makes the wrapped error behave like +/// `ChainedError`. +final class AnyChainedError: ChainedError, CustomChainedErrorDescriptionProtocol { + private let wrappedError: Error + + init(_ error: Error) { + wrappedError = error + } + + var source: Error? { + return (wrappedError as? ChainedError)?.source + } + + var errorDescription: String? { + return wrappedError.localizedDescription + } + + var customErrorDescription: String? { + return (wrappedError as? CustomChainedErrorDescriptionProtocol)?.customErrorDescription + } } |
