ステータスコードの伝播は慎重に
RPCサービスはエラーを調査し、呼び出し元に意味のあるステータスコードを返すことに注意する必要があります。
例として、引数を取らないProductService.GetProductsを呼び出すクライアントを考えてみましょう。
digraph toy_example {
node [style=filled]
client [label="Client"];
product [label="ProductService"];
locale [label="LocaleService"];
client -> product [label="GetProducts"]
product -> locale [label="LocaliseNutritionFacts"]
}
GetProductsの一部として、ProductServiceはすべての製品を取得し、各製品に対してLocaleService.LocaliseNutritionFactsを呼び出すかもしれません。
ProductServiceが誤って実装されている場合、LocaleServiceに間違った引数を渡して、INVALID_ARGUMENTが発生する可能性。
ProductServiceがエラーを呼び出し元に不注意に返すと、クライアントはINVALID_ARGUMENTを受け取ります。
なぜなら、ステータスコードはRPC境界を越えて伝播するからです。
しかし、クライアントはProductService.GetProductsに引数を渡していません。
そのためエラーは無意味なものよりも悪いものです。非常に混乱を招くでしょう。
代わりに、ProductServiceはRPC境界で受信したエラーを調査する必要があります。
つまり、実装するProductService RPCハンドラです。
呼び出し元から無効な引数を取得した場合、INVALID_ARGUMENTを返す必要があります。
下流の何かが無効な引数を受け取った場合、INVALID_ARGUMENTをINTERNALに変換してから呼び出し元にエラーを返す必要があります。
ステータスエラーを不注意に伝播すると、混乱につながります。
さらに悪いことに、すべてのサービスがクライアントエラーを転送しアラートが発生しないため、見えない障害につながる可能性があります。
一般的なルールは、RPC境界ではエラーを調査し、適切なステータスコードで呼び出し元に意味のあるステータスエラーを返すことです。
意味を伝えるために各RPCメソッドは、どのような状況でどのようなエラーコードを返すかを文書化する必要があります。
各メソッドの実装は、文書化されたAPI契約に準拠する必要があります。
ステータスコードの一覧はこちら
https://grpc.io/docs/guides/status-codes/
よく遭遇するケースとしては、複数のサブRPCをコールするもので UNAVAILABLE エラーが返ってくるなど。
サブRPCの UNAVAILABLE なのか、自身のサービスが UNAVAILABLE なのかを区別するためには、ステータスコードを適切に変換する必要があります。