1
votes

I have been recently experimenting with gRPC error handling and wanted to pass in my own proto message to the client (defining my own error details and internal error codes). After searching around, found out couple of examples that uses WithDetails() in gRPC status package to attach custom metadata. I started implementing the same as follows

gRPC proto message

message ErrorInfo {
    int64 error_code = 1;
    string error_message = 2;
    string resource_name = 3;
}

Server-side implementation

// Frame the error message
        st := status.New(codes.NotFound, "object not found")
        errInfo := &api.ErrorInfo {
            ErrorCode: 100,
            ErrorMessage: "Fetching credential failed",
            ResourceName: req.GetBackupLocation().GetCloudCredential(),
        }
        var err error
        st, err = st.WithDetails(errInfo)
        if err != nil {
            // If this errored, it will always error
            // here, so better panic so we can figure
            // out why than have this silently passing.
            panic(fmt.Sprintf("Unexpected error attaching metadata: %v", err))
        }

        return  st.Err()

Client-side implementation

fmt.Printf("line 76 err :%v", err)
                st := status.Convert(err)
                for _, detail := range st.Details() {
                    switch t := detail.(type) {
                    case *api.ErrorInfo:
                        fmt.Printf("error code: %v", t.GetErrorCode())
                        fmt.Printf("error msg: %v", t.GetErrorMessage())
                        fmt.Printf("resource name: %v", t.GetResourceName())
                    }
                }

When i run the code, it hit the Panic() added in the server code which means WithDetails() errored out.

For proceeding further, removed panic on server side, with this client throws the following error

:any: message type "" isn't linked inerror

Questions:

  • Does WithDetails() only work for googleapis/rpc/errdetails standard gRPC proto definition and not with custom proto?
  • Looking at the proto files and code implementation, I don't see anything specific to gRPC errdetails package.

  • When I tried with the proto message from this package, it's working fine.

[ Note: i am using gogo protobuf]

Can any one please let know what is that i am missing here?

2
What's the error returned by WithDetails?Peter
Surprisingly I am not seeing any error being generated, it's null. Is it something to do with gogo proto? The reason for asking this is proto files generated in errdetails package has additional fields like XXX_ but the ones i generated don't have anything. What does this error message any: message type "" isn't linked inerror mean?pkumarn
That error is probably just a consequence of the server doing weird things. Ignore it until you have the server working. If %v formats as <nil> but the error doesn't actually equal nil it's likely a case of nil interface values. I'd consider this a bug in gogo/protobuf. Try the %T verb instead.Peter
1) I tried %T even that gave nil 2) Secondly while searching on google, i came across a link for grpc status package specifically we use gogo proto. Thought will give it a try and tried this package "github.com/gogo/status" . When i use this, things seem to work. I fully don't understand the package implementation.pkumarn
May this commit https://github.com/gogo/status/commit/d60b5acac426cb52f7e28124c6aaa862d9f339f5 fixes the issues i am facing.pkumarn

2 Answers

0
votes

I was facing a similar error (any: message type "" isn't linked in *errors.errorString). In my case it was due to grpc.Status API.

If you're using gogo proto you need to import/use

"github.com/gogo/status"

Instead of

"google.golang.org/grpc/status"

-1
votes

From my point of view, mixing business logic errors with transport errors should not be considered as a good practice, even if GRPC API allows it. Adding special Result or Error structure to every response (with your own set of fields and codes) is much more clean and flexible way to report about request handling state.