HTTPのステータスコードにあたる概念がgRPC Codeであり、以下で定義されている。
https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
例えばGo言語だと以下にprotoから生成されたコードがある。
https://github.com/grpc/grpc-go/blob/master/codes/codes.go
一覧
適当に翻訳していく。
OK = 0
- エラーなし。成功を返した。
- HTTPだと
200 OK
CANCELLED = 1
- 処理がキャンセルされた。通常は呼び出し側によるキャンセル。
- HTTPだと
499 Client Closed Request
※L
を2つ重ねるスペルなことに注意。後述
UNKNOWN = 2
- 不明エラー。他のアドレス空間から受け取ったステータスを、適切にマッピングできなかったときに返される。
- 十分なエラー情報が得られなかったとき、このエラーに変換される可能性がある。
- HTTPだと
500 Internal Server Error
INVALID_ARGUMENT = 3
- クライアントが無効な引数を指定した。
-
FAILED_PRECONDITION
とは異なる。INVALID_ARGUMENT
は、システムの状態にかかわらず問題となる引数(例えば、不正なファイル名)を示す。 - HTTPだと
400 Bad Request
DEADLINE_EXCEEDED = 4
- 操作が完了する前にタイムアウトした。
- システムの状態を変更する操作の場合、操作が正常に完了した場合でもこのエラーが返されることがある。たとえば、サーバーからの成功した応答が、期限が切れるのに十分なだけ長く遅延した可能性がある。
- HTTPだと
504 Gateway Timeout
NOT_FOUND = 5
- 要求されたエンティティ(ファイルやディレクトリなど)が見つからなかった。
- 開発者への注意
- 段階的ロールアウトや秘密のホワイトリストなど、特定のユーザー区分全体に対する要求が拒否された場合は、
NOT_FOUND
を使うことができる。 - ユーザごとのアクセス制御など、一部のユーザに対して要求が拒否された場合、
PERMISSION_DENIED
を使用するべき。
- 段階的ロールアウトや秘密のホワイトリストなど、特定のユーザー区分全体に対する要求が拒否された場合は、
- HTTPだと
404 Not Found
ALREADY_EXISTS = 6
- クライアントが作成しようとしたエンティティ(ファイルやディレクトリなど)が既に存在する。
- HTTPだと
409 Conflict
PERMISSION_DENIED = 7
- 呼び出し元に、操作を実行する権限がない。
-
PERMISSION_DENIED
はリソースを使い果たしたことによる拒否のために使ってはならない- その場合、代わりに
RESOURCE_EXHAUSTED
を使用する
- その場合、代わりに
- 呼び出し側を識別できない場合は、
PERMISSION_DENIED
を使用するべきではない- その場合、代わりに
UNAUTHENTICATED
を使用する。
- その場合、代わりに
- このエラーコードは、要求が有効であること、または要求されたエンティティが存在すること、または他の前提条件を満たすことを意味しない
- HTTPだと
403 Forbidden
UNAUTHENTICATED = 16
- リクエストに適切な認証情報がない
- HTTPだと
401 Unauthorized
RESOURCE_EXHAUSTED = 8
- 一部のリソースが使い果たされている
- ユーザーごとの割り当て量不足
- またはファイルシステム全体のスペース不足
- HTTPだと
429 Too Many Requests
FAILED_PRECONDITION = 9
- システムが操作の実行に必要な状態ではないため、拒否された。
- たとえば、削除するディレクトリが空でない場合、rmdir操作がディレクトリ以外に適用される場合など。
- HTTPだと
400 Bad Request
-
FAILED_PRECONDITION
,ABORTED
,UNAVAILABLE
の使い分け- クライアントが失敗した呼び出しだけを再試行できる場合は
UNAVAILABLE
- クライアントがより高いレベルで再試行する必要がある場合(たとえば、クライアントが指定したテストおよび設定が失敗した場合、クライアントがread-modify-writeシーケンスを再開する必要があることを示す)は、
ABORTED
- システム状態が明示的に修正されるまでクライアントが再試行してはいけない場合は
FAILED_PRECONDITION
を使用する。例えば、ディレクトリが空でないために "rmdir"が失敗した場合、ファイルがディレクトリから削除されない限りクライアントは再試行してはいけないのでFAILED_PRECONDITION
- クライアントが失敗した呼び出しだけを再試行できる場合は
ABORTED = 10
- 操作が中止された。通常、シーケンサチェックの失敗やトランザクションの中止などの同時実行性の問題が原因。
-
FAILED_PRECONDITION
,ABORTED
,UNAVAILABLE
の使い分けは前述のガイドラインを参照。 - HTTPだと
409 Conflict
OUT_OF_RANGE = 11
- 操作が有効範囲を超えて実行された。 たとえば、過去のファイルの終わりを探したり読んだりした。
-
INVALID_ARGUMENT
とは異なり、このエラーはシステム状態が変化した場合に修正されるかもしれない。たとえば、32ビットファイルシステムは、[0,2 ^ 32-1]の範囲にないオフセットで読み込むように要求された場合にはINVALID_ARGUMENT
を生成するべき - 単に、現在のファイルサイズを超えたオフセットから読み込むように要求された場合、それは
OUT_OF_RANGE
を生成するべき -
FAILED_PRECONDITION
とOUT_OF_RANGE
の間にはかなりの重複がある。 - 可能ならば
OUT_OF_RANGE
(より具体的なエラー)を使用することを推奨。ファイルシステムを探索する場合、呼び出し元はOUT_OF_RANGE
を検査すれば終わったかどうか簡単に検出できるようになる。 - HTTPだと
400 Bad Request
UNIMPLEMENTED = 12
- その操作は実装されていないか、サポートされていない。
- HTTPなら
501 Not Implemented
INTERNAL = 13
- 内部エラー
- 基盤となるシステムが期待するいくつかの不変条件が破られたことを意味する。
- このエラーコードは重大なエラーのために予約されている。
- HTTPなら
500 Internal Server Error
UNAVAILABLE = 14
- サービスが現在利用できない。 おそらく一時的な状態で、バックオフで再試行することで修正できる。
-
FAILED_PRECONDITION
,ABORTED
,UNAVAILABLE
の使い分けは前述 - HTTPなら
503 Service Unavailable
DATA_LOSS = 15
- 修復不能なデータ欠損や破損が起きた
- HTTPなら
500 Internal Server Error
gRPC→HTTP 対応表
一応抜き出して表にまとめてみる。概念が1対1ではないことがわかる。単純には比較できないことに注意されたし。
- HTTPはサーバー側のみでステータスを吐くのに対して、gRPCではクライアント側でもエラーを吐くことがある(CANCELLEDとか特に)
gRPC | HTTP |
---|---|
OK = 0 | 200 OK |
CANCELLED = 1 | 499 Client Closed Request |
UNKNOWN = 2 | 500 Internal Server Error |
INVALID_ARGUMENT = 3 | 400 Bad Request |
DEADLINE_EXCEEDED = 4 | 504 Gateway Timeout |
NOT_FOUND = 5 | 404 Not Found |
ALREADY_EXISTS = 6 | 409 Conflict |
PERMISSION_DENIED = 7 | 403 Forbidden |
UNAUTHENTICATED = 16 | 401 Unauthorized |
RESOURCE_EXHAUSTED = 8 | 429 Too Many Requests |
FAILED_PRECONDITION = 9 | 400 Bad Request |
ABORTED = 10 | 409 Conflict |
OUT_OF_RANGE = 11 | 400 Bad Request |
UNIMPLEMENTED = 12 | 501 Not Implemented |
INTERNAL = 13 | 500 Internal Server Error |
UNAVAILABLE = 14 | 503 Service Unavailable |
DATA_LOSS = 15 | 500 Internal Server Error |
gRPC Gatewayでの gRPC→HTTP 対応表
実はprotoと完全一致ではなく、若干アレンジが加わっているようだ。
-
CANCELLED = 1
→408 Request Timeout
-
FAILED_PRECONDITION = 9
→412 Precondition Failed
-
https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go
cancelled? canceled?
CANCELLED
はアメリカ英語つづりではないけど、protoに書かれてるのでこれでいいらしい。
Go版ではわざわざコード中の定数が Canceled
アメリカ英語つづりになるように修正されてた。