Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Critical error handling and presentation #367

Merged
merged 3 commits into from
Jan 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions Lock.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
5B4DE0151DD66DE1004C8AC2 /* EnterpriseDomainInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B4DE0141DD66DE1004C8AC2 /* EnterpriseDomainInteractor.swift */; };
5B4DE0171DD67064004C8AC2 /* EnterpriseActiveAuthPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B4DE0161DD67064004C8AC2 /* EnterpriseActiveAuthPresenter.swift */; };
5B4DE0191DD670F7004C8AC2 /* EnterpriseActiveAuthView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B4DE0181DD670F7004C8AC2 /* EnterpriseActiveAuthView.swift */; };
5B54CDC41E25200900F0AFFF /* UnrecoverableErrorPresenterSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B54CDC31E25200900F0AFFF /* UnrecoverableErrorPresenterSpec.swift */; };
5B55F3C91E24273D00B75CF5 /* UnrecoverableErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B55F3C81E24273D00B75CF5 /* UnrecoverableErrorView.swift */; };
5B55F3CB1E242A2E00B75CF5 /* UnrecoverableErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B55F3CA1E242A2E00B75CF5 /* UnrecoverableErrorPresenter.swift */; };
5B55F3D11E244B8700B75CF5 /* UnrecoverableError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B55F3D01E244B8700B75CF5 /* UnrecoverableError.swift */; };
5B55F3D41E24FFD000B75CF5 /* UnrecoverableErrorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B55F3D21E24F3F000B75CF5 /* UnrecoverableErrorSpec.swift */; };
5B6631531DDB9B28001CB043 /* EnterpriseDomainInteractorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6631511DDB990B001CB043 /* EnterpriseDomainInteractorSpec.swift */; };
5BA563F11DD117550002D3AB /* EnterpriseActiveAuthInteractorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA563EF1DD1171F0002D3AB /* EnterpriseActiveAuthInteractorSpec.swift */; };
5BB4A7C11DF9A38E008E8C37 /* DatabaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB4A7C01DF9A38E008E8C37 /* DatabaseView.swift */; };
Expand Down Expand Up @@ -209,6 +214,11 @@
5B4DE0141DD66DE1004C8AC2 /* EnterpriseDomainInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseDomainInteractor.swift; path = Lock/EnterpriseDomainInteractor.swift; sourceTree = SOURCE_ROOT; };
5B4DE0161DD67064004C8AC2 /* EnterpriseActiveAuthPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseActiveAuthPresenter.swift; path = Lock/EnterpriseActiveAuthPresenter.swift; sourceTree = SOURCE_ROOT; };
5B4DE0181DD670F7004C8AC2 /* EnterpriseActiveAuthView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EnterpriseActiveAuthView.swift; path = Lock/EnterpriseActiveAuthView.swift; sourceTree = SOURCE_ROOT; };
5B54CDC31E25200900F0AFFF /* UnrecoverableErrorPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnrecoverableErrorPresenterSpec.swift; sourceTree = "<group>"; };
5B55F3C81E24273D00B75CF5 /* UnrecoverableErrorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnrecoverableErrorView.swift; sourceTree = "<group>"; };
5B55F3CA1E242A2E00B75CF5 /* UnrecoverableErrorPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = UnrecoverableErrorPresenter.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
5B55F3D01E244B8700B75CF5 /* UnrecoverableError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnrecoverableError.swift; sourceTree = "<group>"; };
5B55F3D21E24F3F000B75CF5 /* UnrecoverableErrorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnrecoverableErrorSpec.swift; sourceTree = "<group>"; };
5B6631511DDB990B001CB043 /* EnterpriseDomainInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseDomainInteractorSpec.swift; sourceTree = "<group>"; };
5BA563EF1DD1171F0002D3AB /* EnterpriseActiveAuthInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnterpriseActiveAuthInteractorSpec.swift; sourceTree = "<group>"; };
5BB4A7C01DF9A38E008E8C37 /* DatabaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseView.swift; sourceTree = "<group>"; };
Expand All @@ -221,7 +231,7 @@
5F1C498F1D8360BF005B74FC /* ConnectionLoadingPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConnectionLoadingPresenter.swift; path = Lock/ConnectionLoadingPresenter.swift; sourceTree = SOURCE_ROOT; };
5F1C49921D8360DF005B74FC /* LoadingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LoadingView.swift; path = Lock/LoadingView.swift; sourceTree = SOURCE_ROOT; };
5F1C49941D8360F5005B74FC /* RemoteConnectionLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RemoteConnectionLoader.swift; path = Lock/RemoteConnectionLoader.swift; sourceTree = SOURCE_ROOT; };
5F1C49951D8360F5005B74FC /* CDNLoaderInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CDNLoaderInteractor.swift; path = Lock/CDNLoaderInteractor.swift; sourceTree = SOURCE_ROOT; };
5F1C49951D8360F5005B74FC /* CDNLoaderInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = CDNLoaderInteractor.swift; path = Lock/CDNLoaderInteractor.swift; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
5F1C499A1D836190005B74FC /* CustomTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CustomTextField.swift; path = Lock/CustomTextField.swift; sourceTree = SOURCE_ROOT; };
5F2037C11D5D02880005D2E2 /* Matchers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Matchers.swift; sourceTree = "<group>"; };
5F2496AE1D66210500A1C6E2 /* LockViewControllerSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockViewControllerSpec.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -311,7 +321,7 @@
5FDB41CD1D2C79FD00166B67 /* Operations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Operations.swift; path = Lock/Operations.swift; sourceTree = SOURCE_ROOT; };
5FDB41CF1D2C95B100166B67 /* MessageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MessageView.swift; path = Lock/MessageView.swift; sourceTree = SOURCE_ROOT; };
5FDC876C1D46DAF200D28596 /* Queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Queue.swift; path = Lock/Queue.swift; sourceTree = SOURCE_ROOT; };
5FE50DBC1D79B8AD00D82290 /* CDNLoaderInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CDNLoaderInteractorSpec.swift; sourceTree = "<group>"; };
5FE50DBC1D79B8AD00D82290 /* CDNLoaderInteractorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CDNLoaderInteractorSpec.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
5FE50DBE1D7A254000D82290 /* ConnectionLoadingPresenterSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionLoadingPresenterSpec.swift; sourceTree = "<group>"; };
5FE50DC01D7DED8C00D82290 /* OfflineConnectionsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OfflineConnectionsSpec.swift; sourceTree = "<group>"; };
5FEADCF41D1A7EBC0032D810 /* LockApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LockApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -377,6 +387,7 @@
5B0CF2D41DE9ADF900F82BF4 /* InputValidationErrorSpec.swift */,
5B0CF2D71DE9B14000F82BF4 /* DatabaseAuthenticatableErrorSpec.swift */,
5B0CF2DC1DE9B47C00F82BF4 /* DatabaseUserCreatorErrorSpec.swift */,
5B55F3D21E24F3F000B75CF5 /* UnrecoverableErrorSpec.swift */,
);
name = Errors;
sourceTree = "<group>";
Expand All @@ -392,6 +403,7 @@
isa = PBXGroup;
children = (
5F2496B51D665AA800A1C6E2 /* InputValidationError.swift */,
5B55F3D01E244B8700B75CF5 /* UnrecoverableError.swift */,
5F2496B91D665AE900A1C6E2 /* DatabaseAuthenticatableError.swift */,
5F2496BB1D665AF700A1C6E2 /* DatabaseUserCreatorError.swift */,
);
Expand Down Expand Up @@ -451,6 +463,7 @@
children = (
5BB4A7C01DF9A38E008E8C37 /* DatabaseView.swift */,
5F1C49921D8360DF005B74FC /* LoadingView.swift */,
5B55F3C81E24273D00B75CF5 /* UnrecoverableErrorView.swift */,
5F73CDD31D3073BE00D8D8D1 /* DatabaseForgotPasswordView.swift */,
5B0971811DC8FAC5003AA88F /* EnterpriseDomainView.swift */,
5B4DE0181DD670F7004C8AC2 /* EnterpriseActiveAuthView.swift */,
Expand Down Expand Up @@ -482,6 +495,7 @@
5FBE5CC91D3EA1380038536D /* MultifactorPresenterSpec.swift */,
5F57DFCD1D4FBE5A00C54DA8 /* AuthPresenterSpec.swift */,
5FE50DBE1D7A254000D82290 /* ConnectionLoadingPresenterSpec.swift */,
5B54CDC31E25200900F0AFFF /* UnrecoverableErrorPresenterSpec.swift */,
5FB06A411E1329FA00E62F36 /* BannerMessagePresenterSpec.swift */,
);
path = Presenters;
Expand Down Expand Up @@ -581,6 +595,7 @@
isa = PBXGroup;
children = (
5F1C498F1D8360BF005B74FC /* ConnectionLoadingPresenter.swift */,
5B55F3CA1E242A2E00B75CF5 /* UnrecoverableErrorPresenter.swift */,
5B09717F1DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift */,
5F73CDD51D30790500D8D8D1 /* DatabaseForgotPasswordPresenter.swift */,
5B4DE0161DD67064004C8AC2 /* EnterpriseActiveAuthPresenter.swift */,
Expand Down Expand Up @@ -961,6 +976,7 @@
5F1C499B1D836190005B74FC /* CustomTextField.swift in Sources */,
5BB4A7C11DF9A38E008E8C37 /* DatabaseView.swift in Sources */,
5FB06A401E131D0300E62F36 /* BannerMessagePresenter.swift in Sources */,
5B55F3D11E244B8700B75CF5 /* UnrecoverableError.swift in Sources */,
5F70F1E71D790773004698DA /* OptionBuildable.swift in Sources */,
5FBE5CB81D3D8F030038536D /* User.swift in Sources */,
5FF0B2281E1726C400A73257 /* CredentialAuth.swift in Sources */,
Expand All @@ -983,6 +999,7 @@
5B0971801DC8F5C4003AA88F /* EnterpriseDomainPresenter.swift in Sources */,
5FC434861D1DF769005188BC /* View.swift in Sources */,
5FDB41CE1D2C79FD00166B67 /* Operations.swift in Sources */,
5B55F3C91E24273D00B75CF5 /* UnrecoverableErrorView.swift in Sources */,
5B09717C1DC8F229003AA88F /* EnterpriseDomain.swift in Sources */,
5F51EE681D1C88FC0024BCD6 /* SignUpView.swift in Sources */,
5F57DFD41D4FE64700C54DA8 /* Auth0OAuth2Interactor.swift in Sources */,
Expand All @@ -995,6 +1012,7 @@
5F70F1E11D790500004698DA /* Connections.swift in Sources */,
5F92C68F1D50EAC200CCE6C0 /* LazyImage.swift in Sources */,
5F2496BA1D665AE900A1C6E2 /* DatabaseAuthenticatableError.swift in Sources */,
5B55F3CB1E242A2E00B75CF5 /* UnrecoverableErrorPresenter.swift in Sources */,
5F57DFC61D4F79DD00C54DA8 /* AuthStyle.swift in Sources */,
5B0971821DC8FAC5003AA88F /* EnterpriseDomainView.swift in Sources */,
5B4DE0191DD670F7004C8AC2 /* EnterpriseActiveAuthView.swift in Sources */,
Expand Down Expand Up @@ -1042,6 +1060,7 @@
5F92C68B1D4FE90F00CCE6C0 /* Auth0OAuth2InteractorSpec.swift in Sources */,
5F5090081D1DE7BA00EAA650 /* NetworkStub.swift in Sources */,
5F0FCF921E201CF300E3D53B /* ObserverStoreSpec.swift in Sources */,
5B55F3D41E24FFD000B75CF5 /* UnrecoverableErrorSpec.swift in Sources */,
5F73CDDC1D309BE900D8D8D1 /* DatabasePasswordInteractorSpec.swift in Sources */,
5F2496AF1D66210500A1C6E2 /* LockViewControllerSpec.swift in Sources */,
5FA250501D48E2A200C544FA /* OptionsSpec.swift in Sources */,
Expand All @@ -1051,6 +1070,7 @@
5F508FFB1D1DB1E700EAA650 /* DatabaseInteractorSpec.swift in Sources */,
5F5F98D41D21E3890016FC22 /* DatabasePresenterSpec.swift in Sources */,
5FA250521D48F08200C544FA /* LockSpec.swift in Sources */,
5B54CDC41E25200900F0AFFF /* UnrecoverableErrorPresenterSpec.swift in Sources */,
5F5F98DC1D22F0B40016FC22 /* RouterSpec.swift in Sources */,
5FBE5CCD1D3EDF960038536D /* UserSpec.swift in Sources */,
5BCDE1361DDDF17F00AA2A6C /* EnterpriseActiveAuthPresenterSpec.swift in Sources */,
Expand Down
23 changes: 14 additions & 9 deletions Lock/CDNLoaderInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,18 @@ struct CDNLoaderInteractor: RemoteConnectionLoader, Loggable {
self.url = URL(string: "client/\(clientId).js", relativeTo: cdnURL(from: baseURL))!
}

func load(_ callback: @escaping (Connections?) -> ()) {
func load(_ callback: @escaping (UnrecoverableError?, Connections?) -> ()) {
self.logger.info("Loading client info from \(self.url)")
let task = URLSession.shared.dataTask(with: self.url, completionHandler: { (data, response, error) in
guard error?._code != NSURLErrorTimedOut else { return callback(.connectionTimeout, nil) }
guard error == nil else {
self.logger.error("Failed to load with error \(error!)")
callback(nil)
return
return callback(.requestIssue, nil)
}

guard let response = response as? HTTPURLResponse else {
self.logger.error("Response was not NSHTTURLResponse")
return callback(nil)
return callback(.requestIssue, nil)
}

let payload: String?
Expand All @@ -52,14 +53,16 @@ struct CDNLoaderInteractor: RemoteConnectionLoader, Loggable {
} else {
payload = nil
}

guard 200...299 ~= response.statusCode else {
self.logger.error("HTTP response was not successful. HTTP \(response.statusCode) <\(payload ?? "No Body")>")
return callback(nil)
guard response.statusCode != 403 else { return callback(.invalidClientOrDomain, nil) }
return callback(.requestIssue, nil)
}

guard var jsonp = payload else {
self.logger.error("HTTP response had no jsonp \(payload ?? "No Body")")
return callback(nil)
return callback(.invalidClientOrDomain, nil)
}

self.logger.verbose("Received jsonp \(jsonp)")
Expand Down Expand Up @@ -93,10 +96,12 @@ struct CDNLoaderInteractor: RemoteConnectionLoader, Loggable {
info.oauth2.forEach { strategy in
strategy.connections.forEach { connections.social(name: $0.name, style: AuthStyle.style(forStrategy: strategy.name, connectionName: $0.name)) }
}
callback(connections)

guard !connections.isEmpty else { return callback(.clientWithNoConnections, connections) }
callback(nil, connections)
} catch let e {
self.logger.error("Failed to parse \(jsonp) with error \(e)")
return callback(nil)
return callback(.invalidClientOrDomain, nil)
}
})
task.resume()
Expand Down Expand Up @@ -143,7 +148,7 @@ private struct ClientInfo {
"waad",
"adfs",
"ad"
]
]

}

Expand Down
11 changes: 9 additions & 2 deletions Lock/ConnectionLoadingPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@ class ConnectionLoadingPresenter: Presentable, Loggable {
var messagePresenter: MessagePresenter?
let loader: RemoteConnectionLoader
let navigator: Navigable
let options: Options

init(loader: RemoteConnectionLoader, navigator: Navigable) {
init(loader: RemoteConnectionLoader, navigator: Navigable, options: Options) {
self.loader = loader
self.navigator = navigator
self.options = options
}

var view: View {
self.loader.load { connections in
self.loader.load { error, connections in
guard error == nil else {
return Queue.main.async {
self.navigator.navigate(.unrecoverableError(error: error!))
}
}
guard let connections = connections, !connections.isEmpty else { return self.navigator.exit(withError: UnrecoverableError.clientWithNoConnections) }
Queue.main.async {
self.logger.debug("Loaded connections. Moving to root view")
Expand Down
7 changes: 0 additions & 7 deletions Lock/Lock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,6 @@ struct ConnectionProvider {
var connections: Connections { return local.select(byNames: allowed) }
}

public enum UnrecoverableError: Error {
case invalidClientOrDomain
case clientWithNoConnections
case missingDatabaseConnection
case invalidOptions(cause: String)
}

private func telemetryFor(authentication: Authentication, webAuth: WebAuth) -> (Authentication, WebAuth) {
var authentication = authentication
var webAuth = webAuth
Expand Down
4 changes: 1 addition & 3 deletions Lock/RemoteConnectionLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,5 @@
import Foundation

protocol RemoteConnectionLoader {

func load(_ callback: @escaping (Connections?) -> ())

func load(_ callback: @escaping (UnrecoverableError?, Connections?) -> ())
}
9 changes: 8 additions & 1 deletion Lock/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct Router: Navigable {
guard !connections.isEmpty else {
self.lock.logger.debug("No connections configured. Loading client info from Auth0...")
let interactor = CDNLoaderInteractor(baseURL: self.lock.authentication.url, clientId: self.lock.authentication.clientId)
return ConnectionLoadingPresenter(loader: interactor, navigator: self)
return ConnectionLoadingPresenter(loader: interactor, navigator: self, options: self.lock.options)
}
if let database = connections.database {
guard self.lock.options.allow != [.ResetPassword] && self.lock.options.initialScreen != .resetPassword else { return forgotPassword }
Expand Down Expand Up @@ -127,6 +127,11 @@ struct Router: Navigable {
return presenter
}

func unrecoverableError(_ error: UnrecoverableError) -> Presentable? {
let presenter = UnrecoverableErrorPresenter(error: error, navigator: self)
return presenter
}

var showBack: Bool {
guard let routes = self.controller?.routes else { return false }
return !routes.history.isEmpty
Expand Down Expand Up @@ -170,6 +175,8 @@ struct Router: Navigable {
presentable = self.multifactor
case .enterpriseActiveAuth(let connection):
presentable = self.EnterpriseActiveAuth(connection)
case .unrecoverableError(let error):
presentable = self.unrecoverableError(error)
default:
self.lock.logger.warn("Ignoring navigation \(route)")
return
Expand Down
5 changes: 4 additions & 1 deletion Lock/Routes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ enum Route: Equatable {
case forgotPassword
case multifactor
case enterpriseActiveAuth(connection: EnterpriseConnection)
case unrecoverableError(error: UnrecoverableError)

func title(withStyle style: Style) -> String? {
switch self {
Expand All @@ -58,7 +59,7 @@ enum Route: Equatable {
return "Two Step Verification".i18n(key: "com.auth0.lock.multifactor.title", comment: "Multifactor title")
case .enterpriseActiveAuth:
return "Corporate Login".i18n(key: "com.auth0.lock.corporate.title", comment: "Corporate Login title")
case .root:
case .root, .unrecoverableError:
return style.hideTitle ? nil : style.title
}
}
Expand All @@ -70,6 +71,8 @@ func == (lhs: Route, rhs: Route) -> Bool {
return true
case (.enterpriseActiveAuth(let lhsConnection), .enterpriseActiveAuth(let rhsConnection)):
return lhsConnection.name == rhsConnection.name
case (.unrecoverableError(let lhsError), .unrecoverableError(let rhsError)):
return lhsError == rhsError
default:
return false
}
Expand Down
Loading