Skip to content

Add rich error handling #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Instructions

Install the go protobuf plugin required:

$ go get github.com/golang/protobuf/protoc-gen-go
$ go install github.com/golang/protobuf/protoc-gen-go

Generate protobuf files:

$ protoc -I ../ ../hello.proto --go_out=plugins=grpc:./hello
Expand Down
25 changes: 24 additions & 1 deletion go/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,32 @@ func main() {
// Want to take specific action based on specific error?
if codes.InvalidArgument == errStatus.Code() {
// do your stuff here
log.Fatal()
}
}

resp, err = c.SayHelloAdvanced(
context.Background(),
&api.HelloReq{Name: "Leonhard Euler"},
)

if err != nil {
// this is advanced error handling. Everything works exactly like the previous example, but in this one you also
// get extra error information
errStatus, _ := status.FromError(err)
fmt.Println(errStatus.Message())
// lets print the error code which is `INVALID_ARGUMENT`
fmt.Println(errStatus.Code())
// now lets get the advanced error info!
for _, d := range errStatus.Details() {
switch errProto := d.(type) {
// in some languages, you may need to unwrap the obj from an any.Any. However, Go grpc lib have done that already for us
case *api.Error:
// following prints the error desc, "Your name contains 14 characters, ..."
fmt.Println(errProto.Description)
default:
log.Fatal("Unexpected type: ", errProto)
}
}
}
fmt.Println(resp.GetResult())
}
211 changes: 161 additions & 50 deletions go/hello/hello.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions go/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ func (s *HelloServer) SayHelloStrict(ctx context.Context, req *api.HelloReq) (*a
return &api.HelloResp{Result: fmt.Sprintf("Hey, %s!", req.GetName())}, nil
}

func (s *HelloServer) SayHelloAdvanced(ctx context.Context, req *api.HelloReq) (*api.HelloResp, error) {
if len(req.GetName()) >= 10 {
// with the error, you can also send any proto object as metadata. We will use the one we defined in the
// proto definition
// so create an api.Error obj and send that along with the error.
detail := &api.Error{
Description: fmt.Sprintf("Your name contains %d characters, but you cannot use more than 10 characters in this API request", len(req.Name)),
}
st := status.New(codes.InvalidArgument, "Length of `Name` cannot be more than 10 characters")
// following attaches the extra error metadata to the error
// in other languages, you may need to wrap the obj within an any.Any. Following `WithDetails` method does that
// for us
st, _ = st.WithDetails(detail)
return nil, st.Err()
}
return &api.HelloResp{Result: fmt.Sprintf("Hey, %s!", req.GetName())}, nil
}

func Serve() {
addr := fmt.Sprintf(":%d", 50051)
conn, err := net.Listen("tcp", addr)
Expand Down
6 changes: 6 additions & 0 deletions hello.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ service HelloService {
// Strict Version responds only to requests which have `Name` length
// less than 10 characters
rpc SayHelloStrict(HelloReq) returns (HelloResp) {};
// Same like previous one, but returns an advanced error, an instance of Error message defined below
rpc SayHelloAdvanced(HelloReq) returns (HelloResp) {};
}

message HelloReq {
Expand All @@ -17,4 +19,8 @@ message HelloReq {

message HelloResp {
string Result = 1;
}

message Error {
string Description = 1;
}
Loading