From ee14ea94d7170cf8838683812c15c550a8867bbc Mon Sep 17 00:00:00 2001 From: Chris Leonavicius Date: Thu, 15 Aug 2024 12:14:05 -0700 Subject: [PATCH] fix: set offline when receiving certain error responses --- Sources/Amplitude/Utilities/HttpClient.swift | 15 ++++++++++--- .../Utilities/HttpClientTests.swift | 21 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Sources/Amplitude/Utilities/HttpClient.swift b/Sources/Amplitude/Utilities/HttpClient.swift index 1e8e7cc4..72964e2e 100644 --- a/Sources/Amplitude/Utilities/HttpClient.swift +++ b/Sources/Amplitude/Utilities/HttpClient.swift @@ -37,10 +37,19 @@ class HttpClient { let request = try getRequest() let requestData = getRequestData(events: events) - sessionTask = session.uploadTask(with: request, from: requestData) { [callbackQueue] data, response, error in + sessionTask = session.uploadTask(with: request, from: requestData) { [callbackQueue, configuration] data, response, error in callbackQueue.async { - if error != nil { - completion(.failure(error!)) + if let error = error { + let nsError = error as NSError + if nsError.domain == NSURLErrorDomain { + switch nsError.code { + case NSURLErrorCannotConnectToHost, NSURLErrorNetworkConnectionLost, NSURLErrorCannotFindHost, NSURLErrorAppTransportSecurityRequiresSecureConnection: + configuration.offline = true + default: + break + } + } + completion(.failure(error)) } else if let httpResponse = response as? HTTPURLResponse { switch httpResponse.statusCode { case 1..<300: diff --git a/Tests/AmplitudeTests/Utilities/HttpClientTests.swift b/Tests/AmplitudeTests/Utilities/HttpClientTests.swift index 3af5c5c0..63159ac2 100644 --- a/Tests/AmplitudeTests/Utilities/HttpClientTests.swift +++ b/Tests/AmplitudeTests/Utilities/HttpClientTests.swift @@ -86,4 +86,25 @@ final class HttpClientTests: XCTestCase { } _ = XCTWaiter.wait(for: [asyncExpectation], timeout: 5) } + + func testUploadWithCannotConnectToHostError() { + let config = Configuration(apiKey: "fake", serverUrl: "http://localhost:3000", offline: false) + let httpClient = HttpClient(configuration: config, diagnostics: diagonostics) + let uploadExpectation = expectation(description: "Did Call Upload") + let event = BaseEvent(userId: "unit-test user", eventType: "unit-test event") + + _ = httpClient.upload(events: "[\(event.toString())]") { result in + switch result { + case .success: + XCTFail("Expected failure") + case .failure(let error): + XCTAssertEqual((error as NSError).code, NSURLErrorCannotConnectToHost) + } + + uploadExpectation.fulfill() + } + + waitForExpectations(timeout: 5) + XCTAssertEqual(config.offline, true) + } }