web-dev-qa-db-ja.com

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)

<_(StatusCode.UNKNOWN、アプリケーションの呼び出し例外:くそー!)で終了したRPCのランデブー>

したがって、技術的にエラーを処理できます。私の問題は...もっと良い方法はありますか?メッセージの説明を変更する良い方法はありますか?ステータスコードを変更できますか?

9
FunkySayu

はい、もっと良い方法があります。 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エラー

2
haio

これには新しいメソッドcontext.abort()もあります-実際には例外を発生させてRPC呼び出しを終了します:

grpc.ServicerContext.abort()

2
Michael

したがって、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'}
0
Neeraj Bansal