使用 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/