Я пытаюсь отправить собственный Proto в ответ на ошибку на мои вызовы grpc. Согласно это, это должно быть возможно.
Вот код.
st := status.Newf(codes.NotFound, "user %s doesn't exist", req.Name)
desc := "The username Doesn't exist, please give a valid username"
customProtoError := &data.Error{
Message: "Check username",
Code: 1404,
Type: "Service",
DetailedMessage: desc,
}
st, err := st.WithDetails(customProtoError)
if err != nil {
panic(fmt.Sprintf("Unexpected error attaching metadata: %v", err))
}
У меня есть обработчики grpc и http для этих API-интерфейсов GRPC. Маршалер, используемый в HTTP-сервере, github.com/gogo/gateway
mux := runtime.NewServeMux(
runtime.WithMarshalerOption(JSONContentType, &gateway.JSONPb{}))
Конфигурация для HTTP и Сервер GRPC доступен здесь. Когда я пытаюсь получить доступ к API с помощью HTTP-вызовов, я получаю в ответ вот что.
Ошибка HTTP:
{
"error": "user kishore1 doesn't exist",
"code": 5,
"message": "user kishore1 doesn't exist",
"details": [
{
"type_url": "type.googleapis.com/data.Error",
"value": "Cg5DaGVjayB1c2VybmFtZRD8ChoHU2t5ZmxvdyI4VGhlIHVzZXJuYW1lIERvZXNuJ3QgZXhpc3QsIHBsZWFzZSBnaXZlIGEgdmFsaWQgdXNlcm5hbWU="
}
]
}
type_url
поставляется с Google, поскольку он жестко запрограммирован в прототипе golang. код. Но это говорит Any
в JSON будет десериализован во встроенные сообщения.
Код клиента Grpc:
resp, err := client.GetUser(ctx, req)
if err != nil {
st := status.Convert(err)
for _, detail := range st.Details() {
switch t := detail.(type) {
case *pb.Error:
fmt.Println("Oops! Your request was rejected by the server.")
...
default:
fmt.Println("Error Received - ", detail, reflect.TypeOf(detail))
}
}
Ошибка Grpc:
Error Received - proto: not found *errors.prefixError
Есть идеи, что могло вызвать этот беспорядок? HTTP не десериализуется как встроенное сообщение, а GRPC выдает proto.NotFound
Может ли это быть из-за того, что шлюзом является gogo proto? Я даже пробовал то же самое с googleapis proto errdetails.BadRequest
, но все равно.