grpc - gRPC 中丰富的错误处理模式

标签 grpc

使用 gRPC 向客户端发送有关错误的更多详细信息的模式是什么?

例如,假设我有一个用于注册用户的表单,用于发送消息

message RegisterUser {
  string email = 1;
  string password = 2;
}

电子邮件的格式必须正确且唯一,密码的长度必须至少为 8 个字符。

如果我编写 JSON API,我会返回 400 错误并包含以下正文:

{
  "errors": [{
    "field": "email",
    "message": "Email does not have proper format."
   }, {
     "field": "password",
     "message": "Password must be at least 8 characters."
   }],
}

客户端可以向用户提供很好的错误消息(即通过突出显示密码字段并明确告诉用户他们的输入有问题)。

使用 gRPC 有没有办法做类似的事情?似乎在大多数客户端语言中,错误会导致抛出异常,而无法获取响应。

例如,我想要类似的东西

message ValidationError {
  string field = 1;
  string message = 2;
}

message RegisterUserResponse {
  repeated ValidationError validation_errors = 1;
  ...
}

或类似的。

最佳答案

在响应元数据中包含其他错误详细信息。但是,仍请确保提供有用的状态代码和消息。在这种情况下,您可以将 RegisterUserResponse 添加到元数据。

在 gRPC Java 中,看起来像:

Metadata.Key<RegisterUserResponse> REGISTER_USER_RESPONSE_KEY =
    ProtoUtils.keyForProto(RegisterUserResponse.getDefaultInstance());
...
Metadata metadata = new Metadata();
metadata.put(REGISTER_USER_RESPONSE_KEY, registerUserResponse);
responseObserver.onError(
    Status.INVALID_ARGUMENT.withDescription("Email or password malformed")
      .asRuntimeException(metadata));

另一个选项是使用google.rpc.Status proto其中包括用于详细信息的附加Any。支持每种语言来处理该类型。在 Java 中,它看起来像:

// This is com.google.rpc.Status, not io.grpc.Status
Status status = Status.newBuilder()
    .setCode(Code.INVALID_ARGUMENT.getNumber())
    .setMessage("Email or password malformed")
    .addDetails(Any.pack(registerUserResponse))
    .build();
responseObserver.onError(StatusProto.toStatusRuntimeException(status));

google.rpc.Status 在某些语言中更清晰,因为错误详细信息可以作为一个单元传递。它还清楚地表明响应的哪些部分与错误相关。在线上,它仍然使用元数据来传递附加信息。

您可能还对 error_details.proto 感兴趣其中包含一些常见的错误类型。

discussed this topic CloudNativeCon 期间。您可以在 YouTube 上查看幻灯片和链接的录制内容。

关于grpc - gRPC 中丰富的错误处理模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48748745/

相关文章:

java - stub 的 gRPC 并发

c++ - 如何在 C++ 中使用 gRPC 同时连接到多个服务器?

Python 无法连接到 grpc channel -> "failed to connect to all addresses" "grpc_status":14

python - gRPC:Rendezvous 终止(StatusCode.INTERNAL,收到 RST_STREAM,错误代码为 2)

java - proto 生成从 jar 文件导入的 java

c++ - 使用 vcpkg 编译 gRPC C++ 示例

grpc 通过反向代理流式传输

go - 将上下文从 gRPC 端点传递到 goroutine 收到上下文取消错误

android - 在 Android 上使用 gRPC 处理文件下载

protocol-buffers - 大型数据集上的 gRPC 序列化缓慢