Last active
August 27, 2018 14:19
-
-
Save Gurpartap/8dbf5d323817a19f98d4c816469903e2 to your computer and use it in GitHub Desktop.
gRPC Status Details (custom error data) with Swift (grpc-objc)
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
func ping() { | |
let req = PingRequest() | |
ExampleService.ping(with: req) { (response, error) in | |
if let error = error { | |
var title = "Unknown error" | |
var message = error.localizedDescription | |
for detail in try! RPCStatus.from(error)?.details ?? [] { | |
switch detail { | |
case let detail as AlertMessage: | |
title = detail.title | |
message = detail.message | |
default: | |
break | |
} | |
} | |
// use title, message to show an alert | |
return | |
} | |
// use response | |
} | |
} |
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
import ExampleRPCSDK | |
let knownErrorDetailClasses = [ | |
RPCRetryInfo.self, | |
RPCDebugInfo.self, | |
RPCQuotaFailure.self, | |
RPCPreconditionFailure.self, | |
RPCBadRequest.self, | |
RPCRequestInfo.self, | |
RPCResourceInfo.self, | |
RPCHelp.self, | |
RPCLocalizedMessage.self, | |
AlertMessage.self, // Custom | |
] | |
extension RPCStatus { | |
class func from(_ error: Error) throws -> RPCStatus? { | |
let nserr = error as NSError | |
guard let trailerMetadata = nserr.userInfo[kGRPCTrailersKey as! AnyHashable] as? Dictionary<String, AnyObject> else { | |
return nil | |
} | |
guard let bin = trailerMetadata["grpc-status-details-bin"] as? Data else { | |
return nil | |
} | |
return try RPCStatus(data: bin) | |
} | |
var details: Array<AnyObject> { | |
return detailsArray | |
.flatMap({ $0 as? GPBAny }) | |
.flatMap({ detail -> AnyObject? in | |
for knownType in knownErrorDetailClasses { | |
if let t = try? detail.unpackMessageClass(knownType) { | |
return t | |
} | |
} | |
return nil | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment