簡単なサービスを考えてみましょう。
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)
<_(StatusCode.UNKNOWN、アプリケーションの呼び出し例外:くそー!)で終了したRPCのランデブー>
したがって、技術的にエラーを処理できます。私の問題は...もっと良い方法はありますか?メッセージの説明を変更する良い方法はありますか?ステータスコードを変更できますか?
はい、もっと良い方法があります。 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!')
。
さまざまな言語でgrpcエラーを処理する方法についての記事があります: gRPCエラー
これには新しいメソッドcontext.abort()もあります-実際には例外を発生させてRPC呼び出しを終了します:
したがって、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'}