Last active
June 2, 2020 05:56
-
-
Save onevcat/4eb605f14a90ee2de6d5930026ba64ef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// For Request and Response defination, see https://onevcat.com/2016/12/pop-cocoa-2/ | |
// Define the possible requests | |
protocol Request { | |
// Every request should have a corresponding Response | |
// Here we want all response could contain error cases | |
associatedtype Response: ErrorResponsable & Decodable | |
//... | |
} | |
// A response which could contain error case. | |
protocol ErrorResponsable { | |
// Error Responsable require a definition of a | |
// structured representation of error, eg, it could be a JSON | |
associatedtype Error: ResponseError | |
} | |
protocol ResponseError { | |
// A method to parse response data to error | |
static func parse(from data: Data) -> Self? | |
} | |
// Shortcut for those errors could be represented by `Decodable` | |
extension ResponseError where Self: Decodable { | |
static func parse(from data: Data) -> Self? { | |
return try? JSONDecoder().decode(Self.self, from: data) | |
} | |
} | |
// Response of User Request. | |
// Normal: {id: 1, name: "Wei Wang"} | |
// Possible Error: {"statusCode": 404, "message": "not found"} or {"statusCode": 401, "message": "Permission Denied"} | |
struct User: ErrorResponsable, Decodable { | |
// Possible error of User | |
struct Error: ResponseError, Decodable { | |
let statusCode: Int | |
let message: String | |
} | |
let id: Int | |
let name: String | |
} | |
struct GetUserRequest: Request { | |
typealias Response = User | |
// ... | |
init(id: Int) { /*...*/ } | |
} | |
GetUserRequest(id: 1).send() | |
.then { user in | |
print(user.name) | |
}.catch { error in | |
// .responseParsingError is thrown by response parser, when the HTTP response body data | |
// cannot be parsed to normal User object. When it happens, it might be due to server returning | |
// an error response. This error is associated with the response data so we could handle it. | |
if case .responseParsingError(let data) = error, | |
// Parse the error from data. This actually could be written in protocol extension of Error, | |
// by doing that, we could maybe just call `error.responseError` to get strong-typed error. | |
let userError = User.Error.parse(from: data) | |
{ | |
print(userError.statusCode) | |
} else { | |
// Not responseParsingError or cannot be parsed to User.Error. Something else happened. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment