From a8c7c1aadd78447aaa536faaaf958b568b8ddd09 Mon Sep 17 00:00:00 2001 From: Ghenadie Vasiliev-Pusca Date: Thu, 1 Aug 2024 13:11:14 +0300 Subject: [PATCH] wip --- .../Clients/HTTPClient/HTTPClient+Live.swift | 26 ++++++++++++++++++- .../HTTPURLSessionResponse.swift | 5 ++++ .../Mobile/RadixConnectMobile.swift | 14 ---------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/RadixWallet/Clients/HTTPClient/HTTPClient+Live.swift b/RadixWallet/Clients/HTTPClient/HTTPClient+Live.swift index fb9e79ba01..035370f4de 100644 --- a/RadixWallet/Clients/HTTPClient/HTTPClient+Live.swift +++ b/RadixWallet/Clients/HTTPClient/HTTPClient+Live.swift @@ -4,7 +4,31 @@ extension HTTPClient { return .init( executeRequest: { request, acceptedStatusCodes in - let (data, urlResponse) = try await session.data(for: request) + let (data, urlResponse) = try await { + // Retrying only once seems to be enough, but better to be on the safe side and retry more. + var retryAttempts = 5 + while retryAttempts > 0 { + do { + return try await session.data(for: request) + } catch { + // Handle the very obscure error when the CFNetwork drops the request after it being sent. + // Note that NSURLErrorNetworkConnectionLost seems to be an opaque error hiding some other + // possible error withing CFNetwork, it does not literally mean that hte network connection + // was actually lost. This error will usually be thrown when the request was made right after + // the app did come to foreground, it happens seldomly, but consistently. + // As a workaround - retry the request if it failed initially. + if let nsError = error as NSError?, + nsError.domain == NSURLErrorDomain, + nsError.code == NSURLErrorNetworkConnectionLost + { + retryAttempts -= 1 + continue + } + throw error + } + } + throw RequestRetryAttemptsExceeded() + }() guard let httpURLResponse = urlResponse as? HTTPURLResponse else { throw ExpectedHTTPURLResponse() diff --git a/RadixWallet/Core/SharedModels/HTTPURLSessionResponse/HTTPURLSessionResponse.swift b/RadixWallet/Core/SharedModels/HTTPURLSessionResponse/HTTPURLSessionResponse.swift index 020ac5c450..0e680b160d 100644 --- a/RadixWallet/Core/SharedModels/HTTPURLSessionResponse/HTTPURLSessionResponse.swift +++ b/RadixWallet/Core/SharedModels/HTTPURLSessionResponse/HTTPURLSessionResponse.swift @@ -3,6 +3,11 @@ public struct ExpectedHTTPURLResponse: Swift.Error { public init() {} } +// MARK: - RequestRetryAttemptsExceeded +public struct RequestRetryAttemptsExceeded: Swift.Error { + public init() {} +} + // MARK: - BadHTTPResponseCode public struct BadHTTPResponseCode: LocalizedError { public let got: Int diff --git a/RadixWallet/RadixConnect/RadixConnect/Mobile/RadixConnectMobile.swift b/RadixWallet/RadixConnect/RadixConnect/Mobile/RadixConnectMobile.swift index d03292bfe1..34d76dcec2 100644 --- a/RadixWallet/RadixConnect/RadixConnect/Mobile/RadixConnectMobile.swift +++ b/RadixWallet/RadixConnect/RadixConnect/Mobile/RadixConnectMobile.swift @@ -15,20 +15,6 @@ extension RadixConnectMobile { } func handleRequest(_ request: URL) async throws { - @Dependency(\.continuousClock) var clock - // A slight delay before handling the request. - // - // This is mainly added to fix the following issue: - // In some cases the Wallet will show the "Failed to validate dApp" alert. - // - // The cause for this issue is that during dApp validation, when Dev mode is not enabled, - // network requests are being made, and seldomly, but quite consistent, the OS will terminate - // the request with the quite obscure message - "Network connection lost". - // Likely that this is because the app is not fully in foreground at the moment the request is being made. - // So adding a small delay allows the OS to be ready to handle the request. Still, this assumption is based - // purely on expirementation, and there might be some other more robust fix. - try? await clock.sleep(for: .milliseconds(100)) - let result = try await radixConnectMobile.handleDeepLink(url: request.absoluteString) incomingMessagesSubject.send( .init(