Skip to content

Instantly share code, notes, and snippets.

@Gurpartap
Last active August 27, 2018 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gurpartap/8dbf5d323817a19f98d4c816469903e2 to your computer and use it in GitHub Desktop.
Save Gurpartap/8dbf5d323817a19f98d4c816469903e2 to your computer and use it in GitHub Desktop.
gRPC Status Details (custom error data) with Swift (grpc-objc)
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
}
}
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