エラーハンドリング

gRPCによるエラーの処理方法と、gRPCのエラーコード。

エラーハンドリング

gRPCによるエラーの処理方法と、gRPCのエラーコード。

標準エラーモデル

概念ドキュメントや例でもご覧いただいたように、gRPC呼び出しが正常に完了すると、サーバーはクライアントにOKステータスを返します(言語によっては、OKステータスがコードで直接使用される場合とされない場合があります)。しかし、呼び出しが成功しなかった場合はどうなるのでしょうか?

エラーが発生した場合、gRPCは代わりにエラーコードのいずれかを返します。オプションの文字列エラーメッセージは、何が起こったのかについての詳細情報を提供します。エラー情報は、サポートされているすべての言語でgRPCクライアントが利用できます。

リッチなエラーモデル

上記で説明したエラーモデルは、公式のgRPCエラーモデルであり、すべてのgRPCクライアント/サーバーライブラリでサポートされており、gRPCデータ形式(プロトコルバッファかそれ以外か)とは無関係です。これはかなり限定的であり、エラー詳細を通信する機能が含まれていないことに気づかれたかもしれません。

ただし、データ形式としてプロトコルバッファを使用している場合は、Googleによって開発および使用されている、こちらで説明されている、よりリッチなエラーモデルの使用を検討する価値があります。このモデルは、サーバーが返すことができ、クライアントが消費できる追加のエラー詳細を、1つ以上のプロトコルメッセージとして表現できるようにします。また、一般的なニーズ(無効なパラメータ、クォータ違反、スタックトレースなど)をカバーするための、標準的なエラーメッセージタイプのセットを指定しています。この追加のエラー情報のプロトコルバッファバイナリエンコーディングは、レスポンスの末尾メタデータとして提供されます。

このリッチなエラーモデルは、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++エラー詳細の例
GoGoエラー処理の例
Goエラー詳細の例
JavaJavaエラー処理の例
Javaエラー詳細の例
NodeNodeエラー処理の例
PythonPythonエラー詳細の例

grpc-errorsリポジトリには、追加のエラー処理例も含まれています。