Let's consider a simple service:
service Something {
rpc Do(Request) returns Response;
}
message Request {
string field = 1;
}
message Response {
string response = 1;
}
Assume I have to do some checking on the Request.field
, I want to raise a client error if the field is invalid:
class MyService(proto_pb2.SomethingServicer):
def Do(self, request, context):
if not is_valid_field(request.field):
raise ValueError("Damn!") # Or something like that
return proto_pb2.Response(response="Yeah!")
With the following client:
channel = grpc.insecure_channel(...)
stub = proto_pb2.SomethingStub(channel)
try:
response = stub.Do(proto_pb2.Request(field="invalid"))
except grpc.RpcError as e:
print(e)
<_Rendezvous of RPC that terminated with (StatusCode.UNKNOWN, Exception calling application: Damn!)>
So I can technically handle errors. My issue is... is there a better way? Is there a good way to change the message description? Can we change the status code?
Yes, there is a better way. You may change the status details using the ServicerContext.set_details
method and you may change the status code using the ServicerContext.set_code
method. I suspect that your servicer will look something like
class MyService(proto_pb2.SomethingServicer):
def Do(self, request, context):
if not is_valid_field(request.field):
context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
context.set_details('Consarnit!')
return proto_pb2.Response()
return proto_pb2.Response(response='Yeah!')
.
There's a new method for this too, context.abort() - it'll actually raise an exception to terminate the RPC call:
grpc.ServicerContext.abort()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With