Skip to content

Fix crash when starting a request on an invalidated session #829

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

Open
wants to merge 2 commits into
base: wpios-edition
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ let package = Package(
targets: [
.binaryTarget(
name: "WordPressKit",
url: "https://github.com/user-attachments/files/18570063/WordPressKit.zip",
checksum: "fc25d3065e80af713dac970db7ed89ff37e4cc98afc98b6a2ecf7b47b2ddd0c1"
url: "https://github.com/user-attachments/files/18647254/WordPressKit.zip",
checksum: "6df9cf41df249237fd03eb09a4dd170b8ce80c4606ad839b2a71b44c5e8495fe"
),
]
)
5 changes: 3 additions & 2 deletions Sources/CoreAPI/WordPressAPIError+NSErrorBridge.swift
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@ extension WordPressAPIError: CustomNSError {
return -100003
case .unknown:
return -100004
case .sessionInvalidated:
return -100005
}
}

@@ -42,8 +44,7 @@ extension WordPressAPIError: CustomNSError {
return (endpointError as NSError).userInfo
case .connection(let error):
return [NSUnderlyingErrorKey: error]
case .requestEncodingFailure, .unacceptableStatusCode, .unparsableResponse,
.unknown:
case .requestEncodingFailure, .unacceptableStatusCode, .unparsableResponse, .sessionInvalidated, .unknown:
return [:]
}
}
6 changes: 4 additions & 2 deletions Sources/CoreAPI/WordPressAPIError.swift
Original file line number Diff line number Diff line change
@@ -19,6 +19,8 @@ import Foundation
case unacceptableStatusCode(response: HTTPURLResponse, body: Data)
/// The API call returned an HTTP response that WordPressKit can't parse. Receiving this error could be an indicator that there is an error response that's not handled properly by WordPressKit.
case unparsableResponse(response: HTTPURLResponse?, body: Data?, underlyingError: Error)
/// Attempting to start a request on an invalidated session.
case sessionInvalidated
/// Other error occured.
case unknown(underlyingError: Error)

@@ -28,7 +30,7 @@ import Foundation

var response: HTTPURLResponse? {
switch self {
case .requestEncodingFailure, .connection, .unknown:
case .requestEncodingFailure, .connection, .unknown, .sessionInvalidated:
return nil
case let .endpointError(error):
return (error as? HTTPURLResponseProviding)?.httpResponse
@@ -49,7 +51,7 @@ extension WordPressAPIError: LocalizedError {
// always returns a non-nil value.
let localizedErrorMessage: String
switch self {
case .requestEncodingFailure, .unparsableResponse, .unacceptableStatusCode:
case .requestEncodingFailure, .unparsableResponse, .unacceptableStatusCode, .sessionInvalidated:
// These are usually programming errors.
localizedErrorMessage = Self.unknownErrorMessage
case let .endpointError(error):
15 changes: 14 additions & 1 deletion Sources/CoreAPI/WordPressComRestApi.swift
Original file line number Diff line number Diff line change
@@ -105,6 +105,8 @@ open class WordPressComRestApi: NSObject {

private var useEphemeralSession: Bool

private var isInvalidated = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about changing those URLSession properties to Optional instead and assigning them to nil in the invalidateAndCancelTasks function?


/**
Configure whether or not the user's preferred language locale should be appended. Defaults to true.
*/
@@ -174,6 +176,10 @@ open class WordPressComRestApi: NSObject {
Cancels all ongoing taks and makes the session invalid so the object will not fullfil any more request
*/
@objc open func invalidateAndCancelTasks() {
guard !isInvalidated else {
return
}
isInvalidated = true
for session in [urlSession, uploadURLSession] {
session.invalidateAndCancel()
}
@@ -202,6 +208,7 @@ open class WordPressComRestApi: NSObject {
success: @escaping SuccessResponseBlock,
failure: @escaping FailureReponseBlock) -> Progress? {
let progress = Progress.discreteProgress(totalUnitCount: 100)
print("GET:", Thread.callStackSymbols)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the print statements before merging.


Task { @MainActor in
let result = await self.perform(.get, URLString: URLString, parameters: parameters, fulfilling: progress)
@@ -247,6 +254,8 @@ open class WordPressComRestApi: NSObject {
parameters: [String: AnyObject]?,
success: @escaping SuccessResponseBlock,
failure: @escaping FailureReponseBlock) -> Progress? {
print("POST:", Thread.callStackSymbols)

let progress = Progress.discreteProgress(totalUnitCount: 100)

Task { @MainActor in
@@ -431,7 +440,11 @@ open class WordPressComRestApi: NSObject {
taskCreated: ((Int) -> Void)? = nil,
session: URLSession? = nil
) async -> APIResult<T> {
await (session ?? self.urlSession)
guard !isInvalidated else {
print("Session Invalidated: ", Thread.callStackSymbols)
return APIResult.failure(.sessionInvalidated)
}
return await (session ?? self.urlSession)
.perform(request: request, taskCreated: taskCreated, fulfilling: progress, errorType: WordPressComRestApiEndpointError.self)
.mapSuccess { response -> HTTPAPIResponse<T> in
let object = try decoder(response.body)
4 changes: 4 additions & 0 deletions Sources/CoreAPI/WordPressOrgXMLRPCApi.swift
Original file line number Diff line number Diff line change
@@ -424,6 +424,10 @@ private extension WordPressAPIError where EndpointError == WordPressOrgXMLRPCApi
error = underlyingError as NSError
data = body
statusCode = nil
case .sessionInvalidated:
error = NSError(domain: WPXMLRPCFaultErrorDomain, code: -1)
data = nil
statusCode = nil
case let .unknown(underlyingError):
error = underlyingError as NSError
data = nil