Handle configuration errors out of VPN status
On configuration error, retain information about the profile that triggered the error. For now, present an alert, but with this information the UI can be easily changed later.
This commit is contained in:
parent
ae748dd1b3
commit
f0c5ecd84f
|
@ -26,6 +26,15 @@
|
|||
import Foundation
|
||||
import PassepartoutCore
|
||||
|
||||
extension Error {
|
||||
var localizedAppDescription: String {
|
||||
if let errorDescription = (self as? PassepartoutError)?.localizedAppDescription, !errorDescription.isEmpty {
|
||||
return "\(errorDescription)."
|
||||
}
|
||||
return localizedDescription
|
||||
}
|
||||
}
|
||||
|
||||
extension PassepartoutError {
|
||||
var localizedAppDescription: String? {
|
||||
let V = L10n.Global.Errors.self
|
||||
|
|
|
@ -30,7 +30,7 @@ struct OrganizerView: View {
|
|||
enum AlertType: Identifiable {
|
||||
case subscribeReddit
|
||||
|
||||
case error(String, Error)
|
||||
case error(String, String)
|
||||
|
||||
// XXX: alert ids
|
||||
var id: Int {
|
||||
|
@ -79,6 +79,11 @@ struct OrganizerView: View {
|
|||
onCompletion: onHostFileImporterResult
|
||||
).onOpenURL(perform: onOpenURL)
|
||||
.themePrimaryView()
|
||||
|
||||
// VPN configuration error publisher (no need to observe VPNManager)
|
||||
.onReceive(VPNManager.shared.configurationError) {
|
||||
alertType = .error($0.profile.header.name, $0.error.localizedAppDescription)
|
||||
}
|
||||
}
|
||||
|
||||
private var hiddenSceneView: some View {
|
||||
|
@ -105,7 +110,7 @@ extension OrganizerView {
|
|||
case .failure(let error):
|
||||
alertType = .error(
|
||||
L10n.Menu.Contextual.AddProfile.fromFiles,
|
||||
error
|
||||
error.localizedDescription
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -129,10 +134,10 @@ extension OrganizerView {
|
|||
}
|
||||
)
|
||||
|
||||
case .error(let title, let error):
|
||||
case .error(let title, let errorDescription):
|
||||
return Alert(
|
||||
title: Text(title),
|
||||
message: Text(error.localizedDescription),
|
||||
message: Text(errorDescription),
|
||||
dismissButton: .cancel(Text(L10n.Global.Strings.ok))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ extension VPNManager {
|
|||
pp_log.error("Unable to build VPNConfiguration: \(error)")
|
||||
|
||||
// UI is certainly interested in configuration errors
|
||||
lastError = error
|
||||
configurationError.send((profile, error))
|
||||
|
||||
throw error
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import TunnelKitOpenVPNManager
|
|||
|
||||
@MainActor
|
||||
public class VPNManager: ObservableObject {
|
||||
public typealias ConfigurationError = (profile: Profile, error: Error)
|
||||
|
||||
// MARK: Initialization
|
||||
|
||||
|
@ -49,7 +50,7 @@ public class VPNManager: ObservableObject {
|
|||
|
||||
public let currentState: ObservableState
|
||||
|
||||
public internal(set) var lastError: Error? {
|
||||
public private(set) var lastError: Error? {
|
||||
get {
|
||||
currentState.lastError
|
||||
}
|
||||
|
@ -58,6 +59,8 @@ public class VPNManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
public let configurationError = PassthroughSubject<ConfigurationError, Never>()
|
||||
|
||||
// MARK: Internals
|
||||
|
||||
private var lastProfile: Profile = .placeholder
|
||||
|
|
Loading…
Reference in New Issue