diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index f1b413d663..dd0610e48c 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -1091,23 +1091,55 @@ func deleteRemoteCtrl(_ rcId: Int64) async throws { try await sendCommandOkResp(.deleteRemoteCtrl(remoteCtrlId: rcId)) } -func networkErrorAlert(_ r: ChatResponse) -> Alert? { +struct ErrorAlert { + var title: LocalizedStringKey + var message: LocalizedStringKey +} + +func getNetworkErrorAlert(_ r: ChatResponse) -> ErrorAlert? { switch r { case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TIMEOUT))): - return mkAlert( - title: "Connection timeout", - message: "Please check your network connection with \(serverHostname(addr)) and try again." - ) + return ErrorAlert(title: "Connection timeout", message: "Please check your network connection with \(serverHostname(addr)) and try again.") case let .chatCmdError(_, .errorAgent(.BROKER(addr, .NETWORK))): - return mkAlert( - title: "Connection error", - message: "Please check your network connection with \(serverHostname(addr)) and try again." - ) + return ErrorAlert(title: "Connection error", message: "Please check your network connection with \(serverHostname(addr)) and try again.") + case let .chatCmdError(_, .errorAgent(.BROKER(addr, .HOST))): + return ErrorAlert(title: "Connection error", message: "Server address is incompatible with network settings: \(serverHostname(addr)).") + case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TRANSPORT(.version)))): + return ErrorAlert(title: "Connection error", message: "Server version is incompatible with your app: \(serverHostname(addr)).") + case let .chatCmdError(_, .errorAgent(.SMP(.PROXY(proxyErr)))): + return proxyErrorAlert(proxyErr) + case let .chatCmdError(_, .errorAgent(.PROXY(_, _, .protocolError(.PROXY(proxyErr))))): + return proxyErrorAlert(proxyErr) default: return nil } } +private func proxyErrorAlert(_ proxyErr: ProxyError) -> ErrorAlert? { + switch proxyErr { + case .BROKER(brokerErr: .TIMEOUT): + return ErrorAlert(title: "Private routing error", message: "Please try later.") + case .BROKER(brokerErr: .NETWORK): + return ErrorAlert(title: "Private routing error", message: "Please try later.") + case .NO_SESSION: + return ErrorAlert(title: "Private routing error", message: "Please try later.") + case .BROKER(brokerErr: .HOST): + return ErrorAlert(title: "Private routing error", message: "Server address is incompatible with network settings.") + case .BROKER(brokerErr: .TRANSPORT(.version)): + return ErrorAlert(title: "Private routing error", message: "Server version is incompatible with network settings.") + default: + return nil + } +} + +func networkErrorAlert(_ r: ChatResponse) -> Alert? { + if let alert = getNetworkErrorAlert(r) { + return mkAlert(title: alert.title, message: alert.message) + } else { + return nil + } +} + func acceptContactRequest(incognito: Bool, contactRequest: UserContactRequest) async { if let contact = await apiAcceptContactRequest(incognito: incognito, contactReqId: contactRequest.apiId) { let chat = Chat(chatInfo: ChatInfo.direct(contact: contact), chatItems: []) diff --git a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift index c8a6efd282..c0cc42bd8e 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListNavLink.swift @@ -564,18 +564,11 @@ func joinGroup(_ groupId: Int64, _ onComplete: @escaping () async -> Void) { } } -struct ErrorAlert { - var title: LocalizedStringKey - var message: LocalizedStringKey -} - func getErrorAlert(_ error: Error, _ title: LocalizedStringKey) -> ErrorAlert { - switch error as? ChatResponse { - case let .chatCmdError(_, .errorAgent(.BROKER(addr, .TIMEOUT))): - return ErrorAlert(title: "Connection timeout", message: "Please check your network connection with \(serverHostname(addr)) and try again.") - case let .chatCmdError(_, .errorAgent(.BROKER(addr, .NETWORK))): - return ErrorAlert(title: "Connection error", message: "Please check your network connection with \(serverHostname(addr)) and try again.") - default: + if let r = error as? ChatResponse, + let alert = getNetworkErrorAlert(r) { + return alert + } else { return ErrorAlert(title: title, message: "Error: \(responseError(error))") } } diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 2d3663b9f8..2129d38fcf 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -1906,6 +1906,7 @@ public enum AgentErrorType: Decodable, Hashable { case SMP(smpErr: ProtocolErrorType) case NTF(ntfErr: ProtocolErrorType) case XFTP(xftpErr: XFTPErrorType) + case PROXY(proxyServer: String, relayServer: String, proxyErr: ProxyClientError) case RCP(rcpErr: RCErrorType) case BROKER(brokerAddress: String, brokerErr: BrokerErrorType) case AGENT(agentErr: SMPAgentError) @@ -1943,13 +1944,23 @@ public enum ProtocolErrorType: Decodable, Hashable { case BLOCK case SESSION case CMD(cmdErr: ProtocolCommandError) + indirect case PROXY(proxyErr: ProxyError) case AUTH + case CRYPTO case QUOTA case NO_MSG case LARGE_MSG + case EXPIRED case INTERNAL } +public enum ProxyError: Decodable, Hashable { + case PROTOCOL(protocolErr: ProtocolErrorType) + case BROKER(brokerErr: BrokerErrorType) + case BASIC_AUTH + case NO_SESSION +} + public enum XFTPErrorType: Decodable, Hashable { case BLOCK case SESSION @@ -1967,6 +1978,12 @@ public enum XFTPErrorType: Decodable, Hashable { case INTERNAL } +public enum ProxyClientError: Decodable, Hashable { + case protocolError(protocolErr: ProtocolErrorType) + case unexpectedResponse(responseStr: String) + case responseError(responseErr: ProtocolErrorType) +} + public enum RCErrorType: Decodable, Hashable { case `internal`(internalErr: String) case identity @@ -1996,6 +2013,7 @@ public enum ProtocolCommandError: Decodable, Hashable { public enum ProtocolTransportError: Decodable, Hashable { case badBlock + case version case largeMsg case badSession case noServerAuth