diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj index 9d82ef4..dccad08 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 2233714028F43D0B009D37D9 /* Error+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2233713F28F43D0B009D37D9 /* Error+Ext.swift */; }; + 2233714228F44645009D37D9 /* WalletService+Ext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2233714128F44645009D37D9 /* WalletService+Ext.swift */; }; 22488A9128E7043200FE29C3 /* String+ArrayConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22C3EEA428E4733C007DB01B /* String+ArrayConversion.swift */; }; 22488A9328E726AA00FE29C3 /* TunnelRouteCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22488A9228E726A900FE29C3 /* TunnelRouteCollection.swift */; }; 22488A9A28E729E600FE29C3 /* GeneralSettingsStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22488A9928E729E600FE29C3 /* GeneralSettingsStorage.swift */; }; @@ -186,6 +188,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2233713F28F43D0B009D37D9 /* Error+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+Ext.swift"; sourceTree = ""; }; + 2233714128F44645009D37D9 /* WalletService+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletService+Ext.swift"; sourceTree = ""; }; 22488A9228E726A900FE29C3 /* TunnelRouteCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelRouteCollection.swift; sourceTree = ""; }; 22488A9928E729E600FE29C3 /* GeneralSettingsStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneralSettingsStorage.swift; sourceTree = ""; }; 22488A9C28E72C4E00FE29C3 /* UserDefaultsStorageStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsStorageStrategy.swift; sourceTree = ""; }; @@ -569,6 +573,7 @@ 22C3EEDB28E48D9A007DB01B /* Foundation */ = { isa = PBXGroup; children = ( + 2233713F28F43D0B009D37D9 /* Error+Ext.swift */, 22C3EEDC28E48D9A007DB01B /* Serializer.swift */, ); path = Foundation; @@ -578,6 +583,7 @@ isa = PBXGroup; children = ( 22C3EEE228E48D9A007DB01B /* SentinelNode+Ext.swift */, + 2233714128F44645009D37D9 /* WalletService+Ext.swift */, ); path = Wallet; sourceTree = ""; @@ -1094,6 +1100,7 @@ 92D6B3FD28E19E20004CF9DF /* AppDelegate.swift in Sources */, 923C371C28E5DA05003CFC03 /* OrderType.swift in Sources */, 225A83B228EED93C00F66619 /* PostDNSRequest.swift in Sources */, + 2233714028F43D0B009D37D9 /* Error+Ext.swift in Sources */, 225A838C28EAE01400F66619 /* SubscriptionsService.swift in Sources */, 92D6B46F28E47E2E004CF9DF /* NodesService.swift in Sources */, 22C3EEA728E4733C007DB01B /* Config.swift in Sources */, @@ -1141,6 +1148,7 @@ 225A83C028EF139A00F66619 /* PostConnectionRequest.swift in Sources */, 225A83AC28EDB3C100F66619 /* InfoEvent.swift in Sources */, 22C3EECE28E48B52007DB01B /* PeersModel.swift in Sources */, + 2233714228F44645009D37D9 /* WalletService+Ext.swift in Sources */, 92D6B41E28E2F64D004CF9DF /* ClientConstants.swift in Sources */, 923C371628E5B9DE003CFC03 /* ContextBuilder.swift in Sources */, 22C3EECD28E48B52007DB01B /* TunnelInterfaceModel.swift in Sources */, diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Extensions/Foundation/Error+Ext.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Extensions/Foundation/Error+Ext.swift new file mode 100644 index 0000000..a05bf73 --- /dev/null +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Extensions/Foundation/Error+Ext.swift @@ -0,0 +1,37 @@ +// +// Error+Ext.swift +// SOLARdVPNCommunityCoreiOS +// +// Created by Lika Vorobeva on 10.10.2022. +// + +import Foundation +import Vapor +import GRPC +import SOLARAPI + +extension Error { + var innerError: InnerError? { + if let grpc = self as? (any GRPCErrorProtocol) { + let status = grpc.makeGRPCStatus() + + return .init(code: status.code.rawValue, message: status.message ?? "unknown_error") + } + + if let networkError = self as? NetworkError { + return .init(code: networkError.code, message: networkError.message ?? "unknown_error") + } + + return nil + } + + func encodedError(status: UInt = 500) -> Abort { + guard let innerError = self.innerError else { + return .init(.internalServerError, reason: self.localizedDescription) + } + guard let reason = innerError.toData()?.string else { + return .init(.internalServerError) + } + return .init(.custom(code: status, reasonPhrase: reason)) + } +} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Extensions/Wallet/WalletService+Ext.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Extensions/Wallet/WalletService+Ext.swift new file mode 100644 index 0000000..21282af --- /dev/null +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Extensions/Wallet/WalletService+Ext.swift @@ -0,0 +1,48 @@ +// +// WalletService+Ext.swift +// SOLARdVPNCommunityCoreiOS +// +// Created by Lika Vorobeva on 10.10.2022. +// + +import Foundation +import SentinelWallet + + +extension WalletServiceError: LocalizedError { + public var errorDescription: String? { + switch self { + case .accountMatchesDestination: + return "account_matches_destination" + case .missingMnemonics: + return "missing_mnemonics" + case .missingAuthorization: + return "missing_authorization" + case .notEnoughTokens: + return "not_enough_tokens" + case .mnemonicsDoNotMatch: + return "mnemonic_do_not_match" + case .savingError: + return "saving_error" + } + } +} + +extension WalletServiceError { + var body: SingleInnerError { + switch self { + case .accountMatchesDestination: + return .init(code: 403, message: localizedDescription) + case .missingMnemonics: + return .init(code: 401, message: localizedDescription) + case .missingAuthorization: + return .init(code: 401, message: localizedDescription) + case .notEnoughTokens: + return .init(code: 402, message: localizedDescription) + case .mnemonicsDoNotMatch: + return .init(code: 401, message: localizedDescription) + case .savingError: + return .init(code: 500, message: localizedDescription) + } + } +} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Utilities/Encoder.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Utilities/Encoder.swift index e03d8e6..6e198ec 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Utilities/Encoder.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Common/Utilities/Encoder.swift @@ -7,14 +7,11 @@ import Foundation -enum EncoderError: LocalizedError { - case failToEncode +enum EncoderError: String, LocalizedError { + case failToEncode = "fail_to_encode" var errorDescription: String? { - switch self { - case .failToEncode: - return "Fail to encode" - } + self.rawValue } } @@ -28,7 +25,7 @@ enum Encoder { let string = String(decoding: result, as: UTF8.self) continuation.resume(returning: string) } catch { - continuation.resume(throwing: EncoderError.failToEncode) + continuation.resume(throwing: EncoderError.failToEncode.encodedError()) } } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift index 907996c..48150f4 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Nodes/NodesRouteCollection.swift @@ -47,7 +47,7 @@ extension NodesRouteCollection { case let .success(response): Encoder.encode(model: response, continuation: continuation) case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) } } }) @@ -66,7 +66,7 @@ extension NodesRouteCollection { case let .success(response): Encoder.encode(model: response, continuation: continuation) case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) } } }) @@ -79,7 +79,7 @@ extension NodesRouteCollection { case let .success(response): Encoder.encode(model: response, continuation: continuation) case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: error.code), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) } } }) diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/Connection/Models/ConnectionModelError.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/Connection/Models/ConnectionModelError.swift index 54e685b..9f79df2 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/Connection/Models/ConnectionModelError.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Tunnel/Connection/Models/ConnectionModelError.swift @@ -10,14 +10,15 @@ import SOLARAPI import SentinelWallet typealias SingleInnerError = SOLARAPI.SingleInnerError +typealias InnerError = SOLARAPI.InnerError enum ConnectionModelError: String, Error { - case signatureGenerationFailed - case nodeIsOffline - case balanceUpdateFailed - case noSubscription - case noQuotaLeft - case tunnelIsAlreadyActive + case signatureGenerationFailed = "signature_generation_failed" + case nodeIsOffline = "node_is_offline" + case balanceUpdateFailed = "balance_update_failed" + case noSubscription = "no_subscription" + case noQuotaLeft = "no_quota_left" + case tunnelIsAlreadyActive = "tunnel_is_already_active" var body: SingleInnerError { switch self { @@ -36,22 +37,3 @@ enum ConnectionModelError: String, Error { } } } - -extension WalletServiceError { - var body: SingleInnerError { - switch self { - case .accountMatchesDestination: - return .init(code: 403, message: "accountMatchesDestination") - case .missingMnemonics: - return .init(code: 401, message: "missingMnemonics") - case .missingAuthorization: - return .init(code: 401, message: "missingAuthorization") - case .notEnoughTokens: - return .init(code: 402, message: "notEnoughTokens") - case .mnemonicsDoNotMatch: - return .init(code: 401, message: "mnemonicsDoNotMatch") - case .savingError: - return .init(code: 500, message: "savingError") - } - } -} diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Wallet/WalletRouteCollection.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Wallet/WalletRouteCollection.swift index d420e66..aff6fdd 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Wallet/WalletRouteCollection.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Root/RouteCollections/Wallet/WalletRouteCollection.swift @@ -7,6 +7,7 @@ import Foundation import Vapor +import SentinelWallet struct WalletRouteCollection: RouteCollection { let context: HasSecurityService & HasWalletStorage & HasWalletService @@ -25,7 +26,7 @@ extension WalletRouteCollection { getWallet() { result in switch result { case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: 500), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) case let .success(wallet): Encoder.encode(model: wallet, continuation: continuation) @@ -42,11 +43,11 @@ extension WalletRouteCollection { return try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in switch context.securityService.restore(from: mnemonic) { case .failure(let error): - continuation.resume(throwing: Abort(.init(statusCode: 500), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) case .success(let result): guard context.securityService.save(mnemonics: mnemonic, for: result) else { - continuation.resume(throwing: Abort(.init(statusCode: 500), reason: "Creation failed")) + continuation.resume(throwing: Abort(.init(statusCode: 500), reason: "creation_failed")) return } context.walletStorage.set(wallet: result) @@ -55,7 +56,7 @@ extension WalletRouteCollection { getWallet() { result in switch result { case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: 500), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) case let .success(wallet): Encoder.encode(model: wallet, continuation: continuation) @@ -71,14 +72,14 @@ extension WalletRouteCollection { let address = context.walletStorage.walletAddress guard let mnemonic = context.securityService.loadMnemonics(for: address) else { - throw Abort(.init(statusCode: 500), reason: "Failed to liad mnemonic") + throw WalletServiceError.missingMnemonics.encodedError() } return try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in getWallet() { result in switch result { case let .failure(error): - continuation.resume(throwing: Abort(.init(statusCode: 500), reason: error.localizedDescription)) + continuation.resume(throwing: error.encodedError()) case let .success(wallet): let response = PostMnemonicResponse(wallet: wallet, mnemonic: mnemonic.joined(separator: " ")) Encoder.encode(model: response, continuation: continuation) @@ -102,7 +103,7 @@ extension WalletRouteCollection { fetchBalance() { result in switch result { case let .failure(error): - completion(.failure(error)) + completion(.failure(error.encodedError())) case let .success(balance): let address = context.walletStorage.walletAddress @@ -119,7 +120,7 @@ extension WalletRouteCollection { context.walletService.fetchBalance { result in switch result { case let .failure(error): - completion(.failure(error)) + completion(.failure(error.encodedError())) case let .success(balances): guard let balance = balances.first(where: { $0.denom == ClientConstants.denom }) else { @@ -128,8 +129,7 @@ extension WalletRouteCollection { } guard let amount = Int(balance.amount) else { - // TODO: Call completion with error - + completion(.failure(EncoderError.failToEncode.encodedError())) return } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift index defe9be..d77416f 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesService.swift @@ -46,27 +46,27 @@ extension NodesService: NodesServiceType { page: Int?, completion: @escaping (Result, Error>) -> Void ) { - nodesProvider.getNodes( - .init( - status: .active, - continentCode: continent?.code, - countryCode: countryCode, - minPrice: minPrice, - maxPrice: maxPrice, - orderBy: orderBy, - query: query, - page: page - ) - ) { [weak self] result in - switch result { - case .failure(let error): - log.error(error) +// nodesProvider.getNodes( +// .init( +// status: .active, +// continentCode: continent?.code, +// countryCode: countryCode, +// minPrice: minPrice, +// maxPrice: maxPrice, +// orderBy: orderBy, +// query: query, +// page: page +// ) +// ) { [weak self] result in +// switch result { +// case .failure(let error): +// log.error(error) completion(.failure(NodesServiceError.failToLoadData)) - case .success(let response): - completion(.success(response)) - self?.loadedNodes = response.data - } - } +// case .success(let response): +// completion(.success(response)) +// self?.loadedNodes = response.data +// } +// } } func getNode( diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift index fb77f1b..36d45ad 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/NodesService/NodesServiceError.swift @@ -7,6 +7,10 @@ import Foundation -enum NodesServiceError: LocalizedError { - case failToLoadData +enum NodesServiceError: String, LocalizedError { + case failToLoadData = "fail_to_load_data" + + var errorDescription: String? { + self.rawValue + } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SecurityService/SecurityService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SecurityService/SecurityService.swift index 7f8dc97..c524678 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SecurityService/SecurityService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SecurityService/SecurityService.swift @@ -10,9 +10,13 @@ import SentinelWallet import HDWallet import SwiftKeychainWrapper -enum SecurityServiceError: Error { - case emptyInput - case invalidInput +enum SecurityServiceError: String, Error { + case emptyInput = "empty_input" + case invalidInput = "invalid_input" + + var errorDescription: String? { + self.rawValue + } } private struct Constants { diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionServiceError.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionServiceError.swift index a4c496a..8f81b6b 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionServiceError.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionServiceError.swift @@ -7,15 +7,16 @@ import Foundation -enum SessionsServiceError: LocalizedError { - case invalidURL +enum SessionsServiceError: String, LocalizedError { + case invalidURL = "invalid_url" - case connectionParsingFailed - case nodeMisconfigured - case noQuota + case connectionParsingFailed = "connection_parsing_failed" + case nodeMisconfigured = "node_misconfigured" + case noQuota = "no_quota" - case serverLocalized(String) - case other(Error) + var errorDescription: String? { + self.rawValue + } } extension SessionsServiceError { diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsService.swift index 1d1689d..fed08d8 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsService.swift @@ -57,7 +57,7 @@ extension SessionsService: SessionsServiceType { id: UInt64, accountAddress: String, signature: String, - completion: @escaping (Result<(Data, PrivateKey), SessionsServiceError>) -> Void + completion: @escaping (Result<(Data, PrivateKey), Error>) -> Void ) { guard var components = URLComponents(string: remoteURLString) else { completion(.failure(SessionsServiceError.invalidURL)) @@ -79,21 +79,17 @@ extension SessionsService: SessionsServiceType { switch result { case .success(let infoResult): guard infoResult.success, let stringData = infoResult.result else { - completion(.failure(.connectionParsingFailed)) + completion(.failure(SessionsServiceError.connectionParsingFailed)) return } guard let data = Data(base64Encoded: stringData), data.bytes.count == 58 else { - completion(.failure(.connectionParsingFailed)) + completion(.failure(SessionsServiceError.connectionParsingFailed)) return } completion(.success((data, wgKey))) case .failure(let error): - #warning("TODO: map error") -// let mapper = Self.mapNetworkError(handleSpecificGenericErrors: { error -> SessionsServiceError? in -// return SessionsServiceError.allCases.first(where: { $0.innerCodes.contains(error.code) }) -// }) -// completion(.failure(error)) + completion(.failure(error)) } } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsServiceType.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsServiceType.swift index d937d31..8a1ef52 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsServiceType.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SessionsService/SessionsServiceType.swift @@ -18,6 +18,6 @@ protocol SessionsServiceType { id: UInt64, accountAddress: String, signature: String, - completion: @escaping (Result<(Data, PrivateKey), SessionsServiceError>) -> Void + completion: @escaping (Result<(Data, PrivateKey), Error>) -> Void ) } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SubscriptionsService/SubscriptionsService.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SubscriptionsService/SubscriptionsService.swift index 593e45d..dd688d6 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SubscriptionsService/SubscriptionsService.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/SubscriptionsService/SubscriptionsService.swift @@ -9,11 +9,15 @@ import Foundation import Combine import SentinelWallet -enum SubscriptionsServiceError: LocalizedError { - case missingMnemonic - case paymentFailed - case faliToCancelSubscription - case activeSession +enum SubscriptionsServiceError: String, LocalizedError { + case missingMnemonic = "missing_mnemonic" + case paymentFailed = "payment_failed" + case faliToCancelSubscription = "fali_to_cancel_subscription" + case activeSession = "active_session" + + var errorDescription: String? { + self.rawValue + } } final class SubscriptionsService { diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Model/TunnelSavingError.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Model/TunnelSavingError.swift index 587457a..cf7605d 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Model/TunnelSavingError.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Model/TunnelSavingError.swift @@ -7,20 +7,24 @@ import Foundation -enum TunnelSavingError: Error { - case nameRequired - case privateKeyRequired - case privateKeyInvalid - case addressInvalid - case listenPortInvalid - case MTUInvalid +enum TunnelSavingError: String, LocalizedError { + case nameRequired = "name_equired" + case privateKeyRequired = "private_key_required" + case privateKeyInvalid = "private_key_invalid" + case addressInvalid = "address_invalid" + case listenPortInvalid = "listen_port_invalid" + case MTUInvalid = "mtu_invalid" - case publicKeyRequired - case publicKeyInvalid - case preSharedKeyInvalid - case allowedIPsInvalid - case endpointInvalid - case persistentKeepAliveInvalid + case publicKeyRequired = "public_key_required" + case publicKeyInvalid = "public_key_invalid" + case preSharedKeyInvalid = "pre_shared_key_invalid" + case allowedIPsInvalid = "allowed_ips_invalid" + case endpointInvalid = "endpoint_invalid" + case persistentKeepAliveInvalid = "persistent_keep_alive_invalid" - case publicKeyDuplicated + case publicKeyDuplicated = "public_key_duplicated" + + var errorDescription: String? { + self.rawValue + } } diff --git a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Service/TunnelsServiceStatusDelegate.swift b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Service/TunnelsServiceStatusDelegate.swift index a6250d7..95ee593 100644 --- a/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Service/TunnelsServiceStatusDelegate.swift +++ b/SolardVPNCommunityCoreiOS/SOLARdVPNCommunityCoreiOS/Services/Tunnel/Service/TunnelsServiceStatusDelegate.swift @@ -15,32 +15,47 @@ public enum TunnelsServiceError: LocalizedError { case addTunnelFailed(systemError: Error) case removeTunnelFailed(systemError: Error) -} - -extension TunnelsServiceError { + public var errorDescription: String? { switch self { case .emptyName: - return "The name of the tunnel is empty" + return "empty_name" case .nameAlreadyExists: - return "The name of the tunnel already exist" + return "name_already_exists" case .loadTunnelsFailed: - return "Fail to load a tunnel" + return "load_tunnels_failed" case .addTunnelFailed: - return "Fail to add a tunnel" + return "add_tunnel_failed" case .removeTunnelFailed: - return "Fail to remove the tunnel" + return "remove_tunnel_failed" } } } -enum TunnelActivationError: Error { +enum TunnelActivationError: LocalizedError { case inactive case startingFailed(systemError: Error) case savingFailed(systemError: Error) case loadingFailed(systemError: Error) case retryLimitReached(lastSystemError: Error) case activationAttemptFailed(wasOnDemandEnabled: Bool) + + var errorDescription: String? { + switch self { + case .inactive: + return "inactive" + case .startingFailed(let systemError): + return "starting_failed: \(systemError.localizedDescription)" + case .savingFailed(let systemError): + return "saving_failed: \(systemError.localizedDescription)" + case .loadingFailed(let systemError): + return "loading_failed: \(systemError.localizedDescription)" + case .retryLimitReached(let lastSystemError): + return "retry_limit_reached: \(lastSystemError.localizedDescription)" + case .activationAttemptFailed: + return "activation_attempt_failed" + } + } } protocol TunnelsServiceStatusDelegate: AnyObject { diff --git a/SolardVPNCommunityCoreiOS/Shared/Extentions/ConfigurationParseError.swift b/SolardVPNCommunityCoreiOS/Shared/Extentions/ConfigurationParseError.swift index dc877a3..61a1995 100644 --- a/SolardVPNCommunityCoreiOS/Shared/Extentions/ConfigurationParseError.swift +++ b/SolardVPNCommunityCoreiOS/Shared/Extentions/ConfigurationParseError.swift @@ -11,7 +11,7 @@ enum ConfigurationParserState { case notInASection } -enum ConfigurationParseError: Error { +enum ConfigurationParseError: LocalizedError { case invalidLine(String.SubSequence) case noInterface case multipleInterfaces @@ -33,4 +33,15 @@ enum ConfigurationParseError: Error { case peerHasUnrecognizedKey(String) case multiplePeersWithSamePublicKey case multipleEntriesForKey(String) + + var errorDescription: String? { + switch self { + case .invalidLine, .noInterface, .multipleInterfaces, .interfaceHasNoPrivateKey, .interfaceHasInvalidPrivateKey, + .interfaceHasInvalidListenPort, .interfaceHasInvalidAddress, .interfaceHasInvalidDNS, + .interfaceHasInvalidMTU, .interfaceHasUnrecognizedKey: + return "invalid_interface" + default: + return "invalid_peer" + } + } } diff --git a/SolardVPNCommunityCoreiOS/Shared/Extentions/NETunnelProviderProtocol+Extension.swift b/SolardVPNCommunityCoreiOS/Shared/Extentions/NETunnelProviderProtocol+Extension.swift index 9523710..5e54d8e 100644 --- a/SolardVPNCommunityCoreiOS/Shared/Extentions/NETunnelProviderProtocol+Extension.swift +++ b/SolardVPNCommunityCoreiOS/Shared/Extentions/NETunnelProviderProtocol+Extension.swift @@ -6,12 +6,16 @@ import NetworkExtension import WireGuardKit -enum PacketTunnelProviderError: String, Error { +enum PacketTunnelProviderError: String, LocalizedError { case savedProtocolConfigurationIsInvalid case dnsResolutionFailure case couldNotStartBackend case couldNotDetermineFileDescriptor case couldNotSetNetworkSettings + + var errorDescription: String? { + self.rawValue + } } extension NETunnelProviderProtocol {