Skip to content

Commit

Permalink
#16: Unify errors
Browse files Browse the repository at this point in the history
  • Loading branch information
lika-vorobeva committed Oct 10, 2022
1 parent 6908255 commit 4005402
Show file tree
Hide file tree
Showing 18 changed files with 231 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -186,6 +188,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
2233713F28F43D0B009D37D9 /* Error+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+Ext.swift"; sourceTree = "<group>"; };
2233714128F44645009D37D9 /* WalletService+Ext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletService+Ext.swift"; sourceTree = "<group>"; };
22488A9228E726A900FE29C3 /* TunnelRouteCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelRouteCollection.swift; sourceTree = "<group>"; };
22488A9928E729E600FE29C3 /* GeneralSettingsStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneralSettingsStorage.swift; sourceTree = "<group>"; };
22488A9C28E72C4E00FE29C3 /* UserDefaultsStorageStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsStorageStrategy.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -569,6 +573,7 @@
22C3EEDB28E48D9A007DB01B /* Foundation */ = {
isa = PBXGroup;
children = (
2233713F28F43D0B009D37D9 /* Error+Ext.swift */,
22C3EEDC28E48D9A007DB01B /* Serializer.swift */,
);
path = Foundation;
Expand All @@ -578,6 +583,7 @@
isa = PBXGroup;
children = (
22C3EEE228E48D9A007DB01B /* SentinelNode+Ext.swift */,
2233714128F44645009D37D9 /* WalletService+Ext.swift */,
);
path = Wallet;
sourceTree = "<group>";
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down
Original file line number Diff line number Diff line change
@@ -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))
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand All @@ -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())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
})
Expand All @@ -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())
}
}
})
Expand All @@ -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())
}
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Foundation
import Vapor
import SentinelWallet

struct WalletRouteCollection: RouteCollection {
let context: HasSecurityService & HasWalletStorage & HasWalletService
Expand All @@ -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)
Expand All @@ -42,11 +43,11 @@ extension WalletRouteCollection {
return try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation<String, Error>) 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)
Expand All @@ -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)
Expand All @@ -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<String, Error>) 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)
Expand All @@ -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
Expand All @@ -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 {
Expand All @@ -128,8 +129,7 @@ extension WalletRouteCollection {
}

guard let amount = Int(balance.amount) else {
// TODO: Call completion with error

completion(.failure(EncoderError.failToEncode.encodedError()))
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,27 @@ extension NodesService: NodesServiceType {
page: Int?,
completion: @escaping (Result<PageResponse<Node>, 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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 4005402

Please sign in to comment.