Grpc-gateway: customize the error return

Created on 1 Jun 2017  Â·  21Comments  Â·  Source: grpc-ecosystem/grpc-gateway

If the input type is error, gateway will return a json.

I need to customize the message. Is there a way ?

➜  ~ git:(master) ✗ curl 'localhost:9998/v1/example/echo?name=dddd'
{"error":"strconv.ParseInt: parsing \"dddd\": invalid syntax","code":3}%

the name is int32

enhancement help wanted

Most helpful comment

I think this can be closed now that https://github.com/grpc-ecosystem/grpc-gateway/pull/515 has been merged.

All 21 comments

Have a look at this PR: https://github.com/grpc-ecosystem/grpc-gateway/pull/397

Is there a specific reason why you would want to customize the message? Will a HTTP 400 suffice?

I am working at ksyun openapi, we need to let the return format be the same. So we need to customize.

https://docs.ksyun.com/read/latest/116/_book/KLSAPI/CancelRecordTask.html

@jinleileiking , you might be out of luck. gRPC protocol defines its status using a Status proto. https://github.com/grpc/grpc-go/pull/1156
https://github.com/grpc/grpc-go/blob/master/status/status.go

Gateway just turns that into a JSON object.

@jinleileiking , I think you need to set the HTTPError for runtime.Servemux. See https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/mux.go#L98

+1
I'm having the same issue.
@pieterlouw I was going to create a PR exactly the same with #397 , until I see this issue.

@TamalSaha Hi, our company is recently trying to build micro services using grpc-gateway, and I'm using HTTPError to handle errors. In this case, the error HTTPError receives is the error from "strconv.ParseInt()". I can not assert that, a ParseInt() error is an InvalidArgument error, and then return a HTTP 4xx. More detail is needed, HTTPError has to know what exactly is happening.

Hi, I created a PR #409 , it's almost the same with #397 .
For we are blocked by this issue, if there is anything I can help with, please let me know.
Thank you!

A workaround I've used is to have server pass the error details via a trailer metadata, the on the grpc-gateway side, override the HTTPError handler to read from the trailer metadata.

This doesn't quite work for grpc-gateway side errors; for those I just special cased them in the HTTPError handler.

I will test lately.

The return message is:

{"error":"type mismatch, parameter: num, error: strconv.ParseInt: parsing \"aaa\": invalid syntax","code":3}

We should completely customize this return.( Use template?)

We should not change the core code. We need a config file ??? to set this line:

+       return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", {{$param | printf "%q"}}, err)
@jinleileiking , I think you need to set the HTTPError for runtime.Servemux. See https://github.com/grpc-ecosystem/grpc-gateway/blob/master/runtime/mux.go#L98

It seems the way to solve this problem. I will dig into it.

We should export handleForwardResponseServerMetadata

I'm also looking forward to being able to return custom errors, or at the very least, serialize also status details I'm sending from the server.

@ewang would you be kind to share some code samples? I was also looking at https://github.com/grpc/grpc-go/pull/506. But, I'm interested in reviewing different implementations, especially those involving grpc-gateway.

gRPC-Go now supports using status.WithDetails, however, DefaultHTTPError https://github.com/grpc-ecosystem/grpc-gateway/blob/e4b8a938efae14de11fd97311e873e989896348c/runtime/errors.go#L81 does not support marshalling this. I'm not sure this is the right place to put this but I didn't want to raise a new issue while this issue was still open. @tmc, your thoughts?

I wrote a tiny patch that fixes this in the one case I tried:

diff --git a/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
index 8eebdcf4..445bf46c 100644
--- a/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
+++ b/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go
@@ -63,8 +63,9 @@ var (
 )

 type errorBody struct {
-       Error string `protobuf:"bytes,1,name=error" json:"error"`
-       Code  int32  `protobuf:"varint,2,name=code" json:"code"`
+       Error   string        `protobuf:"bytes,1,name=error" json:"error"`
+       Code    int32         `protobuf:"varint,2,name=code" json:"code"`
+       Details []interface{} `json:"details"`
 }

 //Make this also conform to proto.Message for builtin JSONPb Marshaler
@@ -90,8 +91,9 @@ func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w
        }

        body := &errorBody{
-               Error: s.Message(),
-               Code:  int32(s.Code()),
+               Error:   s.Message(),
+               Code:    int32(s.Code()),
+               Details: s.Details(),
        }

        buf, merr := marshaler.Marshal(body)

Not quite sure what to put in the protobuf field of the Details type. Thoughts appreciated.

On second thought this probably won't work with []interface as the type as it may be used in proto marshallers. At the same time using []*any.Any does not marshal properly without some help.

I think this can be closed now that https://github.com/grpc-ecosystem/grpc-gateway/pull/515 has been merged.

I do not know #51 whether solve this problem. Let the project member to close this issue.

I think #515 sufficiently addresses the issue. Let's close it and if there are more things you would like to see in the error response let's open another issue. After all, the default handler now serves the included error, and you can override the error handler.

Do we have a workaround for this? I think that the issue OP addressed hasn't been resolved. I would like to hide the implementation details from the user. For example, a message like this exposes unnecessary information:

strconv.ParseInt: parsing \"-3000000000000000000000000000000000000\": value out of range

Our documentation site contains from more details on how to customize your error handling: https://grpc-ecosystem.github.io/grpc-gateway/docs/customizingyourgateway.html. Join us in #grpc-gateway on gophers slack if you need more help.

Was this page helpful?
0 / 5 - 0 ratings