Gracefully handling gRPC errors in a Go server / Python client setup

Etienne Bouché
Sep 2, 2018 · 2 min read

gRPC is an awesome protocol for achieving microservices-based infrastructure. It is fast, it is built on top of protocol buffers, which means that you can quickly implement it in multiple languages and that the client and the server aren’t necessarily defined in the same language.

However there are some constraints, one of which is that the clarity and the maturity of the gRPC APIs varies across languages. gRPC was built with Go in mind. The gRPC package for Go is well documented and exposes features that aren’t quite as easy to get in its equivalent Python module.

At Kuranda Labs, we went the microservices route for the backend, using Go as our primarily language. The REST API gateway is a Python Flask server. We had in mind to leverage the full potential of gRPC with easy to write microservices and an easy to write API, yet in two different languages.

Error handling

One domain where the Python implementation of gRPC lacks support in my opinion is error handling.

Let’s look at a concrete example, using the hello world example from grpc-go Github.

We could modify the code to return an error whenever the user is called Martin and fill the gRPC status with details because we want to add extra information:

That being said, how do we intercept from Python client code that the error actually happened, and importantly, how do we get the details of the error? The good news is that it is possible. The bad news is that it is not straight-forward at least at the moment. I am using the following Python packages:

grpcio-tools==1.13.0, protobuf==3.6.0, googleapis-common-protos==1.6.0b4

Notice that googleapis-common-protos is a pre-release. Indeed, the latest stable release (1.5.3, Setp. 2017) does not support all possible error details defined in the Go package. This is a first caveat. The version I use does support all of them but it is much more recent (July 2018).

On the client, what you typically find on the Internet is that you have to catch grpc.RpcError . This is indeed the first step. Getting the details is a little more code though:

Here is the code for get_status_metadata which actually retrieves the error details contained in the gRPC status. These details are passed as trailing metadata which is a list of tuple (key, value) . We are looking for the key grpc-status-details or grpc-status-details-bin . The -bin is appended whenever gRPC pass bytes instead of an HTTP ascii string (see more on this here).

And here is the function unpack_details that does the magic:

If you print st and metadata now you would get:

That’s it :)

Kuranda Labs Engineering

Technology-focused and developers-focused articles from Kuranda Labs

Etienne Bouché

Written by

CEO and co-founder at Kuranda Labs

Kuranda Labs Engineering

Technology-focused and developers-focused articles from Kuranda Labs

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade