アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

gRPC Application のエラー設計

Web アプリケーションで error code, error message を返したくなる時があるはずです。HTTP JSON API とかでたまに見るのは status code が 200 なのに error が返ってくるものです。gRPC ではどうすれば良いのでしょうか。基本をおさらいしつつ浅く考えてみます。

Status Code

成功すると response と status code OK が返ってきます。

何かしらのエラーが発生すると OK 以外のエラー status code が返ってきます。statuscodes.md にも記載されてますが、これらのコードは必ずしも server から返るわけではなく、client 自身が返す場合もあります。

基本的には gRPC アプリケーションで発生したエラーによって status code を変更するような設計にするかと思います。しかし、時には gRPC server (low level) で発生したエラーとアプリケーションのロジックで発生したエラーを分けたい & client にそのエラーの詳細を伝えたいといった事があるかと思います。そのような時は Richer error model を採用しましょう。

Error Details

Google では開発に使用しているエラーモデルが存在します。このモデルに記述されている details がどんなエラーが発生していたのかを詳しく表現できるようなフィールドになってます。Google では一般的なエラーのニーズ(リトライ情報、不正なパラメータの情報など)をカバーできるように proto が定義されてます。これらのような proto を details のフィールドへ格納することで表現することができます。

gRPC ではこのモデルに沿ってエラーを返せるようになってます。エラー詳細は response に付属される metadata 内に details というキーに対して格納されて返ってきます。

  • エラーコード
    • status code
  • エラーメッセージ (ライブラリの実装に依存するとのこと)
    • Go や Nodejs では error として手に入る
    • Go (server) -> PHP (client) だと details に string として含まれて手に入る
      • 例: {"metadata":{},"code":5,"details":"sql: no rows in result set"}
  • エラー詳細: gRPC の response に付属される metadata に details というキーに対して格納されて返ってくる

もちろん Google が定義した proto メッセージではなく、自前で proto を定義するのもありでしょう。

まとめ

  • gRPC では OK 以外はエラーとして扱うことを推奨されてる
  • エラー詳細は response の metadata を使う。details というキーに対して格納していく。

お試し

gRPC の server, client の挙動の確認ができる testing-grpc というものを作りました。このプロジェクトは grpc/grpc-go を使って開発されてますが、他の言語で(例えば PHP)実装された gRPC server, client にも同様の知識を応用できるのではないかと考えてます。

(もし宜しければ github star をお待ちしてます)

github.com

asciicast