使用grpc向客户端引发服务器错误

时间:2016-12-06 14:52:12

标签: python error-handling grpc

让我们考虑一个简单的服务:

service Something {
    rpc Do(Request) returns Response;
}

message Request {
    string field = 1;
}

message Response {
    string response = 1; 
}

假设我必须对Request.field进行一些检查,如果该字段无效,我想提出一个客户端错误:

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!")

使用以下客户端:

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)
  

< _Reddezvous终止于(StatusCode.UNKNOWN,异常调用应用程序:该死!)>

所以我可以在技术上处理错误。我的问题是......有更好的方法吗?有没有一种改变消息描述的好方法?我们可以更改状态代码吗?

4 个答案:

答案 0 :(得分:12)

是的,还有更好的方法。您可以使用ServicerContext.set_details方法更改状态详细信息,并可以使用ServicerContext.set_code方法更改状态代码。我怀疑你的服务员看起来像

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!')

答案 1 :(得分:2)

还有一个新的方法,context.abort() - 它实际上会引发异常以终止RPC调用:

grpc.ServicerContext.abort()

答案 2 :(得分:1)

有一篇关于如何使用各种语言处理grpc错误的文章: gRPC Errors

答案 3 :(得分:0)

因此,在gRPC端,有人可以使用以下方法中止上下文: grpc.ServicerContext.abort()

在客户端(python):

try:
    result = {'msg', 'success'}
except grpc.RpcError as e:
    if e.code() == grpc.StatusCode.INVALID_ARGUMENT:
        result = {'msg', 'invalid arg error'}
    elif e.code() == grpc.StatusCode.ALREADY_EXISTS:
        result = {'msg', 'already exists error'}