1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
//
// DisplayChainedError.swift
// MullvadVPN
//
// Created by pronebird on 04/06/2020.
// Copyright © 2020 Mullvad VPN AB. All rights reserved.
//
import Foundation
protocol DisplayChainedError {
var errorChainDescription: String? { get }
}
extension RestError: DisplayChainedError {
var errorChainDescription: String? {
switch self {
case .network(let urlError):
return String(
format: NSLocalizedString("Network error: %@", comment: ""),
urlError.localizedDescription
)
case .server(let serverError):
if let knownErrorDescription = serverError.errorDescription {
return knownErrorDescription
} else {
return String(
format: NSLocalizedString("Server error: %@", comment: ""),
serverError.error ?? "(empty)"
)
}
case .encodePayload:
return NSLocalizedString("Server request encoding error", comment: "")
case .decodeSuccessResponse:
return NSLocalizedString("Server success response decoding error", comment: "")
case .decodeErrorResponse:
return NSLocalizedString("Server error response decoding error", comment: "")
}
}
}
extension TunnelManager.Error: DisplayChainedError {
var errorChainDescription: String? {
switch self {
case .loadAllVPNConfigurations(let systemError):
return String(format: NSLocalizedString("Failed to load system VPN configurations: %@", comment: ""), systemError.localizedDescription)
case .reloadVPNConfiguration(let systemError):
return String(format: NSLocalizedString("Failed to reload a VPN configuration: %@", comment: ""), systemError.localizedDescription)
case .saveVPNConfiguration(let systemError):
return String(format: NSLocalizedString("Failed to save a VPN tunnel configuration: %@", comment: ""), systemError.localizedDescription)
case .obtainPersistentKeychainReference(_):
return NSLocalizedString("Failed to obtain the persistent keychain reference for the VPN configuration", comment: "")
case .startVPNTunnel(let systemError):
return String(format: NSLocalizedString("System error when starting the VPN tunnel: %@", comment: ""), systemError.localizedDescription)
case .removeVPNConfiguration(let systemError):
return String(format: NSLocalizedString("Failed to remove the system VPN configuration: %@", comment: ""), systemError.localizedDescription)
case .removeInconsistentVPNConfiguration(let systemError):
return String(format: NSLocalizedString("Failed to remove the outdated system VPN configuration: %@", comment: ""), systemError.localizedDescription)
case .readTunnelSettings(_):
return NSLocalizedString("Failed to read tunnel settings", comment: "")
case .addTunnelSettings(_):
return NSLocalizedString("Failed to add tunnel settings", comment: "")
case .updateTunnelSettings(_):
return NSLocalizedString("Failed to update tunnel settings", comment: "")
case .removeTunnelSettings(_):
return NSLocalizedString("Failed to remove tunnel settings", comment: "")
case .pushWireguardKey(let restError):
let reason = restError.errorChainDescription ?? ""
var message = String(format: NSLocalizedString("Failed to send the WireGuard key to server: %@", comment: ""), reason)
if case .server(.keyLimitReached) = restError {
message.append("\n\n")
message.append(NSLocalizedString("Remove unused WireGuard keys and try again", comment: ""))
}
return message
case .replaceWireguardKey(let restError):
let reason = restError.errorChainDescription ?? ""
var message = String(format: NSLocalizedString("Failed to replace the WireGuard key on server: %@", comment: ""), reason)
if case .server(.keyLimitReached) = restError {
message.append("\n\n")
message.append(NSLocalizedString("Remove unused WireGuard keys and try again", comment: ""))
}
return message
case .removeWireguardKey:
// This error is never displayed anywhere
return nil
case .verifyWireguardKey(let restError):
let reason = restError.errorChainDescription ?? ""
return String(format: NSLocalizedString("Failed to verify the WireGuard key on server: %@", comment: ""), reason)
case .missingAccount:
return NSLocalizedString("Internal error: missing account", comment: "")
}
}
}
extension Account.Error: DisplayChainedError {
var errorChainDescription: String? {
switch self {
case .createAccount(let restError), .verifyAccount(let restError):
return restError.errorChainDescription
case .tunnelConfiguration(let tunnelError):
return tunnelError.errorChainDescription
}
}
}
extension AppStorePaymentManager.Error: DisplayChainedError {
var errorChainDescription: String? {
switch self {
case .noAccountSet:
return NSLocalizedString("Internal error: account is not set", comment: "")
case .readReceipt(let readReceiptError):
switch readReceiptError {
case .refresh(let storeError):
return String(format: NSLocalizedString("Cannot refresh the AppStore receipt: %@", comment: ""), storeError.localizedDescription)
case .io(let ioError):
return String(format: NSLocalizedString("Cannot read the AppStore receipt from disk: %@", comment: ""), ioError.localizedDescription)
case .doesNotExist:
return NSLocalizedString("AppStore receipt is not found on disk.", comment: "")
}
case .sendReceipt(let restError):
let reason = restError.errorChainDescription ?? ""
let format = NSLocalizedString(#"""
Failed to send the receipt to server: %@
Please retry by using the "Restore purchases" button.
"""#, comment: "")
return String(format: format, reason)
case .storePayment(let storeError):
return storeError.localizedDescription
}
}
}
|