エラー処理
gRPCのエラー処理方法とgRPCエラーコード。
エラー処理
標準エラーモデル
コンセプトドキュメントと例で見たように、gRPC呼び出しが正常に完了すると、サーバーはクライアントに`OK`ステータスを返します(言語によっては、`OK`ステータスがコードで直接使用される場合と使用されない場合があります)。しかし、呼び出しが成功しなかった場合はどうなりますか?
エラーが発生した場合、gRPCは代わりにエラーステータスコードのいずれかを返します。オプションの文字列エラーメッセージには、発生した事象に関する詳細情報が提供されます。エラー情報は、サポートされているすべての言語のgRPCクライアントで利用できます。
リッチエラーモデル
上記のエラーモデルは公式のgRPCエラーモデルであり、すべてのgRPCクライアント/サーバーライブラリでサポートされており、gRPCデータ形式(プロトコルバッファなど)とは無関係です。お気づきかもしれませんが、これはかなり限定的であり、エラーの詳細を伝える機能は含まれていません。
ただし、データ形式としてプロトコルバッファを使用している場合は、こちらで説明されている、Googleによって開発および使用されているリッチエラーモデルの使用を検討することをお勧めします。このモデルにより、サーバーは1つ以上のprotobufメッセージとして表現された追加のエラー詳細を返し、クライアントはそれを消費できます。さらに、無効なパラメータ、クォータ違反、スタックトレースなど、最も一般的なニーズをカバーするための標準のエラーメッセージタイプのセットを指定しています。この追加のエラー情報のprotobufバイナリエンコーディングは、レスポンスのトレーリングメタデータとして提供されます。
このリッチエラーモデルは、C++、Go、Java、Python、およびRubyライブラリで既にサポートされており、少なくともgrpc-webおよびNode.jsライブラリには、それを要求する未解決の問題があります。他の言語ライブラリは、需要があれば将来的にサポートを追加する可能性があるため、興味がある場合はgithubリポジトリを確認してください。ただし、Cで記述されたgrpc-coreライブラリは、意図的にデータ形式に依存しないため、サポートされる可能性は低いことに注意してください。
プロトコルバッファを使用していない場合でも、同様のアプローチ(エラー詳細をトレーリングレスポンスメタデータに配置)を使用できますが、APIで実際に使用するには、このデータにアクセスするためのライブラリサポートを見つけるか、開発する必要があるでしょう。
ただし、このような拡張エラーモデルを使用するかどうかを決定する際には、以下の重要な考慮事項に注意する必要があります。
- 拡張エラーモデルのライブラリ実装は、エラー詳細ペイロードの要件と期待値に関して、言語間で一貫していない場合があります
- 既存のプロキシ、ロガー、およびその他の標準HTTPリクエストプロセッサは、エラー詳細を認識できないため、監視などの目的で活用できません
- トレーラーに追加のエラー詳細があると、ヘッドオブラインブロッキングが妨げられ、キャッシュミスの頻度が高くなるため、HTTP/2ヘッダー圧縮効率が低下します
- エラー詳細ペイロードが大きくなると、プロトコルの制限(最大ヘッダーサイズなど)に達する可能性があり、元のエラーが事実上失われます
エラーステータスコード
エラーは、ネットワーク障害から認証されていない接続まで、さまざまな状況でgRPCによって発生し、それぞれが特定のステータスコードに関連付けられています。次のエラーステータスコードは、すべてのgRPC言語でサポートされています。
一般的なエラー
ケース | ステータスコード |
---|---|
クライアントアプリケーションがリクエストをキャンセルしました | GRPC_STATUS_CANCELLED |
サーバーがステータスを返す前にデッドラインが切れました | GRPC_STATUS_DEADLINE_EXCEEDED |
サーバーでメソッドが見つかりません | GRPC_STATUS_UNIMPLEMENTED |
サーバーがシャットダウンしています | GRPC_STATUS_UNAVAILABLE |
サーバーが例外をスローしました(または、ステータスコードを返す以外の方法でRPCを終了しました) | GRPC_STATUS_UNKNOWN |
ネットワーク障害
ケース | ステータスコード |
---|---|
デッドラインが切れる前にデータが送信されませんでした。また、一部のデータが送信され、デッドラインが切れる前に他の障害が検出されなかった場合にも適用されます | GRPC_STATUS_DEADLINE_EXCEEDED |
接続が切断される前に、一部のデータが送信されました(たとえば、リクエストメタデータがTCP接続に書き込まれました) | GRPC_STATUS_UNAVAILABLE |
プロトコルエラー
ケース | ステータスコード |
---|---|
解凍できませんでしたが、圧縮アルゴリズムはサポートされています | GRPC_STATUS_INTERNAL |
クライアントで使用されている圧縮メカニズムは、サーバーではサポートされていません | GRPC_STATUS_UNIMPLEMENTED |
フロー制御リソース制限に達しました | GRPC_STATUS_RESOURCE_EXHAUSTED |
フロー制御プロトコル違反 | GRPC_STATUS_INTERNAL |
返されたステータスの解析エラー | GRPC_STATUS_UNKNOWN |
認証されていません:資格情報がメタデータを取得できませんでした | GRPC_STATUS_UNAUTHENTICATED |
認証メタデータに無効なホストが設定されています | GRPC_STATUS_UNAUTHENTICATED |
レスポンスプロトコルバッファの解析エラー | GRPC_STATUS_INTERNAL |
リクエストプロトコルバッファの解析エラー | GRPC_STATUS_INTERNAL |
言語サポート
標準エラーとリッチエラー詳細の処理方法に関するサンプルコードは、複数の言語で利用できます。
言語 | 例 |
---|---|
C++ | C++エラー処理例 |
C++エラー詳細例 | |
Go | Goエラー処理例 |
Goエラー詳細例 | |
Java | Javaエラー処理例 |
Javaエラー詳細例 | |
Node | Nodeエラー処理例 |
Python | Pythonエラー詳細例 |
grpc-errorsリポジトリには、追加のエラー処理例も含まれています。