Как отправить пользовательский протокол в подробностях объекта ошибки статуса grpc

Я пытаюсь отправить собственный 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, но все равно.


person Kishore Bandi    schedule 14.05.2020    source источник


Ответы (1)


Потратив около дня, я понял, что проблема связана с несовместимыми версиями. Вот что у меня сработало при использовании gogo proto.

Из-за ошибок GRPC мне пришлось обновить мою версию grpc-gateway и использовать gogo/status вместо grpc/status

github.com/gogo/status v1.1.0
github.com/grpc-ecosystem/grpc-gateway v1.14.5

Из-за ошибок HTTP мне пришлось понизить версию моего golang/protobuf

github.com/golang/protobuf v1.3.2
person Kishore Bandi    schedule 14.05.2020