diff --git a/CHANGELOG.md b/CHANGELOG.md index e19037527..f6dc67cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,15 @@ # Parse-Swift Changelog ### main -[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.3.2...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift) +[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.3.3...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift) * _Contributing to this repo? Add info about your change here to be included in the next release_ +### 5.3.3 +[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.3.2...5.3.3), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.3.3/documentation/parseswift) + +__Fixes__ +* Only retry connections on specific codes ([#84](https://github.com/netreconlab/Parse-Swift/pull/84)), thanks to [Corey Baker](https://github.com/cbaker6). + ### 5.3.2 [Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.3.1...5.3.2), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.3.2/documentation/parseswift) diff --git a/README.md b/README.md index aa886bcb2..a8c55def3 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ import PackageDescription let package = Package( name: "YOUR_PROJECT_NAME", dependencies: [ - .package(url: "https://github.com/netreconlab/Parse-Swift", .upToNextMajor(from: "5.1.1")), + .package(url: "https://github.com/netreconlab/Parse-Swift", .upToNextMajor(from: "5.3.3")), ] ) ``` diff --git a/Sources/ParseSwift/Extensions/URLSession.swift b/Sources/ParseSwift/Extensions/URLSession.swift index 49028b2dd..7e359a786 100644 --- a/Sources/ParseSwift/Extensions/URLSession.swift +++ b/Sources/ParseSwift/Extensions/URLSession.swift @@ -172,16 +172,6 @@ internal extension URLSession { return } - // If there is current response data, update the client now. - if allowIntermediateResponses { - let result = await self.makeResult(request: request, - responseData: responseData, - urlResponse: urlResponse, - responseError: nil, - mapper: mapper) - completion(result) - } - var delayInterval = TimeInterval() // Check for constant delays in header information. @@ -206,10 +196,30 @@ internal extension URLSession { } } - default: + case 408, 425, 500, 504: if let interval = Utility.computeDelay(Utility.reconnectInterval(2)) { delayInterval = interval } + + default: + // Don't retry based on error code. + let result = await self.makeResult(request: request, + responseData: responseData, + urlResponse: urlResponse, + responseError: nil, + mapper: mapper) + completion(result) + return + } + + // If there is current response data, update the client now. + if allowIntermediateResponses { + let result = await self.makeResult(request: request, + responseData: responseData, + urlResponse: urlResponse, + responseError: nil, + mapper: mapper) + completion(result) } if delayInterval < 1.0 { @@ -218,11 +228,6 @@ internal extension URLSession { let delayIntervalNanoSeconds = UInt64(delayInterval * 1_000_000_000) try await Task.sleep(nanoseconds: delayIntervalNanoSeconds) - // Update requestId in header for Idempotency - var request = request - if request.allHTTPHeaderFields?["X-Parse-Request-Id"] != nil { - request.allHTTPHeaderFields?["X-Parse-Request-Id"] = API.createUniqueRequestId() - } await self.dataTask(with: request, callbackQueue: callbackQueue, attempts: attempts, diff --git a/Sources/ParseSwift/Parse.swift b/Sources/ParseSwift/Parse.swift index bb43d2395..1926cc8a0 100644 --- a/Sources/ParseSwift/Parse.swift +++ b/Sources/ParseSwift/Parse.swift @@ -58,6 +58,9 @@ internal func initialize(applicationId: String, configuration.isMigratingFromObjcSDK = migratingFromObjcSDK configuration.isTestingSDK = testing configuration.isTestingLiveQueryDontCloseSocket = testLiveQueryDontCloseSocket + if testing && maxConnectionAttempts == 5 { + configuration.maxConnectionAttempts = 1 + } try await initialize(configuration: configuration) } diff --git a/Sources/ParseSwift/ParseConstants.swift b/Sources/ParseSwift/ParseConstants.swift index 1abcdbf48..72ebdf524 100644 --- a/Sources/ParseSwift/ParseConstants.swift +++ b/Sources/ParseSwift/ParseConstants.swift @@ -10,7 +10,7 @@ import Foundation enum ParseConstants { static let sdk = "swift" - static let version = "5.3.2" + static let version = "5.3.3" static let fileManagementDirectory = "parse/" static let fileManagementPrivateDocumentsDirectory = "Private Documents/" static let fileManagementLibraryDirectory = "Library/" diff --git a/Tests/ParseSwiftTests/APICommandMultipleAttemptsTests.swift b/Tests/ParseSwiftTests/APICommandMultipleAttemptsTests.swift index 3e1fc8222..68817be8a 100644 --- a/Tests/ParseSwiftTests/APICommandMultipleAttemptsTests.swift +++ b/Tests/ParseSwiftTests/APICommandMultipleAttemptsTests.swift @@ -41,6 +41,7 @@ class APICommandMultipleAttemptsTests: XCTestCase { clientKey: "clientKey", primaryKey: "primaryKey", serverURL: url, + maxConnectionAttempts: 2, testing: true) } @@ -71,7 +72,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { errorKey: errorValue, codeKey: codeValue ] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in @@ -104,7 +104,7 @@ class APICommandMultipleAttemptsTests: XCTestCase { await currentAttempts.incrementAttempts() let current = await currentAttempts.attempts DispatchQueue.main.async { - if current >= Parse.configuration.maxConnectionAttempts { + if current == 1 { expectation1.fulfill() } } @@ -115,7 +115,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { } func testErrorHTTPReturns400NoDataFromServer() async throws { - Parse.configuration.maxConnectionAttempts = 2 let originalError = ParseError(code: .otherCause, message: "Could not decode") MockURLProtocol.mockRequests { _ in return MockURLResponse(error: originalError) // Status code defaults to 400 @@ -155,7 +154,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { let headerKey = "x-rate-limit-reset" let headerValue = "2" let headerFields = [headerKey: headerValue] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in @@ -219,7 +217,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss z" let headerValue = dateFormatter.string(from: date) let headerFields = [headerKey: headerValue] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in @@ -272,7 +269,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { errorKey: errorValue, codeKey: codeValue ] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in @@ -328,7 +324,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { let headerKey = "retry-after" let headerValue = "2" let headerFields = [headerKey: headerValue] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in @@ -392,7 +387,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss z" let headerValue = dateFormatter.string(from: date) let headerFields = [headerKey: headerValue] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in @@ -445,7 +439,6 @@ class APICommandMultipleAttemptsTests: XCTestCase { errorKey: errorValue, codeKey: codeValue ] - Parse.configuration.maxConnectionAttempts = 2 let currentAttempts = Result() MockURLProtocol.mockRequests { _ in diff --git a/Tests/ParseSwiftTests/APICommandTests.swift b/Tests/ParseSwiftTests/APICommandTests.swift index 063361211..ff33d443b 100644 --- a/Tests/ParseSwiftTests/APICommandTests.swift +++ b/Tests/ParseSwiftTests/APICommandTests.swift @@ -213,7 +213,6 @@ class APICommandTests: XCTestCase { errorKey: errorValue, codeKey: codeValue ] - Parse.configuration.maxConnectionAttempts = 1 MockURLProtocol.mockRequests { _ in do { @@ -245,7 +244,6 @@ class APICommandTests: XCTestCase { } func testErrorHTTPReturns400NoDataFromServer() async { - Parse.configuration.maxConnectionAttempts = 1 let originalError = ParseError(code: .otherCause, message: "Could not decode") MockURLProtocol.mockRequests { _ in return MockURLResponse(error: originalError) // Status code defaults to 400 @@ -270,7 +268,6 @@ class APICommandTests: XCTestCase { // This is how errors HTTP errors should typically come in func testErrorHTTP500JSON() async { - Parse.configuration.maxConnectionAttempts = 1 let parseError = ParseError(code: .connectionFailed, message: "Connection failed") let errorKey = "error" let errorValue = "yarr" @@ -311,7 +308,6 @@ class APICommandTests: XCTestCase { } func testErrorHTTPReturns500NoDataFromServer() async { - Parse.configuration.maxConnectionAttempts = 1 let originalError = ParseError(code: .otherCause, message: "Could not decode") MockURLProtocol.mockRequests { _ in var response = MockURLResponse(error: originalError) diff --git a/Tests/ParseSwiftTests/ParseHealthCombineTests.swift b/Tests/ParseSwiftTests/ParseHealthCombineTests.swift index 4a5093b1b..acc6e19f8 100644 --- a/Tests/ParseSwiftTests/ParseHealthCombineTests.swift +++ b/Tests/ParseSwiftTests/ParseHealthCombineTests.swift @@ -86,7 +86,7 @@ class ParseHealthCombineTests: XCTestCase { } MockURLProtocol.mockRequests { _ in - return MockURLResponse(data: encoded, statusCode: 200) + return MockURLResponse(data: encoded, statusCode: 503) } ParseHealth.checkPublisher() @@ -119,7 +119,7 @@ class ParseHealthCombineTests: XCTestCase { } MockURLProtocol.mockRequests { _ in - return MockURLResponse(data: encoded, statusCode: 200) + return MockURLResponse(data: encoded, statusCode: 429) } ParseHealth.checkPublisher() @@ -153,7 +153,7 @@ class ParseHealthCombineTests: XCTestCase { } MockURLProtocol.mockRequests { _ in - return MockURLResponse(data: encoded, statusCode: 200) + return MockURLResponse(data: encoded, statusCode: 429) } ParseHealth.checkPublisher()