From a5a238d55473f1944658e9d0cf6d81fd0b213d32 Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Thu, 6 Feb 2020 13:18:33 +0300 Subject: [PATCH] pass micro errors from grpc server to grpc client (#1167) * pass micro errors from grpc server to grpc client Signed-off-by: Vasiliy Tolstov * wrap micro errors.Error to grpc status Signed-off-by: Vasiliy Tolstov --- error.go | 16 ++++++++++------ grpc_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/error.go b/error.go index 07a31c7..b625d1d 100644 --- a/error.go +++ b/error.go @@ -12,17 +12,21 @@ func microError(err error) error { return nil } - // micro error - if v, ok := err.(*errors.Error); ok { - return v + if verr, ok := err.(*errors.Error); ok { + return verr } // grpc error if s, ok := status.FromError(err); ok { - if e := errors.Parse(s.Message()); e.Code > 0 { - return e // actually a micro error + details := s.Details() + if len(details) == 0 { + if e := errors.Parse(s.Message()); e.Code > 0 { + return e // actually a micro error + } + return errors.InternalServerError("go.micro.client", s.Message()) } - return errors.InternalServerError("go.micro.client", s.Message()) + // return first error from details + return details[0].(error) } // do nothing diff --git a/grpc_test.go b/grpc_test.go index 16d34e7..1b37dad 100644 --- a/grpc_test.go +++ b/grpc_test.go @@ -7,6 +7,7 @@ import ( "github.com/micro/go-micro/v2/client" "github.com/micro/go-micro/v2/client/selector" + "github.com/micro/go-micro/v2/errors" "github.com/micro/go-micro/v2/registry" "github.com/micro/go-micro/v2/registry/memory" pgrpc "google.golang.org/grpc" @@ -18,6 +19,9 @@ type greeterServer struct{} // SayHello implements helloworld.GreeterServer func (g *greeterServer) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + if in.Name == "Error" { + return nil, &errors.Error{Id: "1", Code: 99, Detail: "detail"} + } return &pb.HelloReply{Message: "Hello " + in.Name}, nil } @@ -84,4 +88,25 @@ func TestGRPCClient(t *testing.T) { t.Fatalf("Got unexpected response %v", rsp.Message) } } + + req := c.NewRequest("helloworld", "/helloworld.Greeter/SayHello", &pb.HelloRequest{ + Name: "Error", + }) + + rsp := pb.HelloReply{} + + err = c.Call(context.TODO(), req, &rsp) + if err == nil { + t.Fatal("nil error received") + } + + verr, ok := err.(*errors.Error) + if !ok { + t.Fatalf("invalid error received %#+v\n", err) + } + + if verr.Code != 99 && verr.Id != "1" && verr.Detail != "detail" { + t.Fatalf("invalid error received %#+v\n", verr) + } + }