-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathWordPressAPIError.swift
69 lines (62 loc) · 3.15 KB
/
WordPressAPIError.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import Foundation
public enum WordPressAPIError<EndpointError>: Error where EndpointError: LocalizedError {
static var unknownErrorMessage: String {
NSLocalizedString(
"wordpress-api.error.unknown",
value: "Something went wrong, please try again later.",
comment: "Error message that describes an unknown error had occured"
)
}
/// Can't encode the request arguments into a valid HTTP request. This is a programming error.
case requestEncodingFailure(underlyingError: Error)
/// Error occured in the HTTP connection.
case connection(URLError)
/// The API call returned an error result. For example, an OAuth endpoint may return an 'incorrect username or password' error, an upload media endpoint may return an 'unsupported media type' error.
case endpointError(EndpointError)
/// The API call returned an status code that's unacceptable to the endpoint.
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 = URLError(.cannotParseResponse))
/// Other error occured.
case unknown(underlyingError: Error)
var response: HTTPURLResponse? {
switch self {
case .requestEncodingFailure, .connection, .unknown:
return nil
case let .endpointError(error):
return (error as? HTTPURLResponseProviding)?.httpResponse
case .unacceptableStatusCode(let response, _):
return response
case .unparsableResponse(let response, _, _):
return response
}
}
}
extension WordPressAPIError: LocalizedError {
public var errorDescription: String? {
// Considering `WordPressAPIError` is the error that's surfaced from this library to the apps, its instanes
// may be displayed on UI directly. To prevent Swift's default error message (i.e. "This operation can't be
// completed. <SwiftTypeName> (code=...)") from being displayed, we need to make sure this implementation
// always returns a non-nil value.
let localizedErrorMessage: String
switch self {
case .requestEncodingFailure, .unparsableResponse, .unacceptableStatusCode:
// These are usually programming errors.
localizedErrorMessage = Self.unknownErrorMessage
case let .endpointError(error):
localizedErrorMessage = error.errorDescription ?? Self.unknownErrorMessage
case let .connection(error):
localizedErrorMessage = error.localizedDescription
case let .unknown(underlyingError):
if let msg = (underlyingError as? LocalizedError)?.errorDescription {
localizedErrorMessage = msg
} else {
localizedErrorMessage = Self.unknownErrorMessage
}
}
return localizedErrorMessage
}
}
protocol HTTPURLResponseProviding {
var httpResponse: HTTPURLResponse? { get }
}