错误处理
gRPC 如何处理错误以及 gRPC 错误码。
错误处理
标准错误模型
正如您在我们的概念文档和示例中看到的那样,当 gRPC 调用成功完成时,服务器会向客户端返回 OK
状态(根据语言,OK
状态可能在您的代码中直接使用,也可能不使用)。但是,如果调用不成功会发生什么情况呢?
如果发生错误,gRPC 会返回其错误状态码之一,并带有一个可选的字符串错误消息,提供有关发生情况的更多详细信息。错误信息可供所有受支持语言的 gRPC 客户端使用。
更丰富的错误模型
上面描述的错误模型是官方的 gRPC 错误模型,所有 gRPC 客户端/服务器库都支持它,并且独立于 gRPC 数据格式(无论是 Protocol Buffers 还是其他格式)。您可能已经注意到它非常有限,并且不包含传达错误详细信息的功能。
但是,如果您使用 Protocol Buffers 作为数据格式,则可能希望考虑使用 Google 开发和使用的更丰富的错误模型,如 此处所述。此模型使服务器能够返回并使客户端能够使用表示为一个或多个 protobuf 消息的其他错误详细信息。它进一步指定了一组 标准错误消息类型来满足最常见的需求(例如无效参数、配额违规和堆栈跟踪)。此额外错误信息的 protobuf 二进制编码作为响应中的尾部元数据提供。
C++、Go、Java、Python 和 Ruby 库已支持此更丰富的错误模型,并且至少 grpc-web 和 Node.js 库存在请求它的未解决问题。如果需要,其他语言库将来可能会添加支持,因此如有兴趣,请查看其 GitHub 存储库。但是请注意,用 C 编写的 grpc-core 库可能永远不会支持它,因为它有意与数据格式无关。
如果您未使用 Protocol Buffers,可以使用类似的方法(将错误详细信息放入尾部响应元数据中),但是您可能需要查找或开发库支持以访问此数据,以便在您的 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 |
在 authority 元数据中设置了无效的主机 | GRPC_STATUS_UNAUTHENTICATED |
错误解析响应协议缓冲区 | GRPC_STATUS_INTERNAL |
错误解析请求协议缓冲区 | GRPC_STATUS_INTERNAL |
语言支持
提供了多个语言的示例代码,说明如何处理标准错误以及更丰富的错误详细信息。
语言 | 示例 |
---|---|
C++ | C++ 错误处理示例 |
C++ 错误详细信息示例 | |
Go | Go 错误处理示例 |
Go 错误详细信息示例 | |
Java | Java 错误处理示例 |
Java 错误详细信息示例 | |
Node | Node 错误处理示例 |
Python | Python 错误详细信息示例 |
grpc-errors 存储库还包含其他错误处理示例。