使用 grpc 向客户端发送服务器错误
Raising a server error to the client with 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)
<_Rendezvous of RPC that terminated with (StatusCode.UNKNOWN, Exception calling application: Damn!)>
所以我可以在技术上处理错误。我的问题是......有更好的方法吗?有什么好的方法可以更改消息描述?我们可以更改状态代码吗?
是的,有更好的方法。您可以使用 ServicerContext.set_details
method and you may change the status code using the 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!')
.
还有一个新方法,context.abort() - 它实际上会引发异常以终止 RPC 调用:
关于如何处理各种语言的grpc错误,有一篇文章:
gRPC Errors
所以在 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'}
让我们考虑一个简单的服务:
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)
<_Rendezvous of RPC that terminated with (StatusCode.UNKNOWN, Exception calling application: Damn!)>
所以我可以在技术上处理错误。我的问题是......有更好的方法吗?有什么好的方法可以更改消息描述?我们可以更改状态代码吗?
是的,有更好的方法。您可以使用 ServicerContext.set_details
method and you may change the status code using the 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!')
.
还有一个新方法,context.abort() - 它实际上会引发异常以终止 RPC 调用:
关于如何处理各种语言的grpc错误,有一篇文章: gRPC Errors
所以在 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'}