add error handling example
This commit is contained in:
parent
9069494e7f
commit
bc61ba9c6e
|
@ -19,8 +19,10 @@ import (
|
|||
"gitea.dwysokinski.me/Kichiyaki/grpc-g2a/proto"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const defaultAddress = "localhost:50001"
|
||||
|
@ -30,6 +32,8 @@ const (
|
|||
exampleServer = "server"
|
||||
exampleClient = "client"
|
||||
exampleBidirectional = "bidirectional"
|
||||
exampleJames = "james"
|
||||
exampleJamesError = "jameserror"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -64,6 +68,10 @@ func main() {
|
|||
switch example {
|
||||
case exampleUnary:
|
||||
sayHello(ctx, client, logger)
|
||||
case exampleJames:
|
||||
sayHelloToJames(ctx, client, logger)
|
||||
case exampleJamesError:
|
||||
sayHelloToJamesError(ctx, client, logger)
|
||||
case exampleServer:
|
||||
sayHelloServerStream(ctx, client, logger)
|
||||
case exampleClient:
|
||||
|
@ -77,12 +85,16 @@ func main() {
|
|||
|
||||
func parseExample() string {
|
||||
example := ""
|
||||
flag.StringVar(
|
||||
&example,
|
||||
"example",
|
||||
flag.StringVar(&example, "example", exampleUnary, fmt.Sprintf(
|
||||
"%s, %s, %s, %s, %s or %s (default: %s)",
|
||||
exampleUnary,
|
||||
fmt.Sprintf("%s, %s, %s or %s (default: %s)", exampleUnary, exampleServer, exampleClient, exampleBidirectional, exampleUnary),
|
||||
)
|
||||
exampleJames,
|
||||
exampleJamesError,
|
||||
exampleServer,
|
||||
exampleClient,
|
||||
exampleBidirectional,
|
||||
exampleUnary,
|
||||
))
|
||||
flag.Parse()
|
||||
return example
|
||||
}
|
||||
|
@ -133,6 +145,46 @@ func sayHello(ctx context.Context, client proto.GreeterClient, logger *zap.Logge
|
|||
logger.Info("reply received", zap.String("message", reply.GetMessage()))
|
||||
}
|
||||
|
||||
func sayHelloToJames(ctx context.Context, client proto.GreeterClient, logger *zap.Logger) {
|
||||
name := "James"
|
||||
logger.Info("sending request", zap.String("name", name))
|
||||
reply, err := client.SayHelloToJames(ctx, &proto.HelloRequest{Name: name})
|
||||
if err != nil {
|
||||
logger.Fatal("something went wrong while calling SayHello", zap.Error(err))
|
||||
}
|
||||
logger.Info("reply received", zap.String("message", reply.GetMessage()))
|
||||
}
|
||||
|
||||
func sayHelloToJamesError(ctx context.Context, client proto.GreeterClient, logger *zap.Logger) {
|
||||
name := "SomeoneElse"
|
||||
|
||||
logger.Info("sending request", zap.String("name", name))
|
||||
reply, err := client.SayHelloToJames(ctx, &proto.HelloRequest{Name: name})
|
||||
if err == nil {
|
||||
logger.Info("unexpected reply received", zap.String("message", reply.GetMessage()))
|
||||
return
|
||||
}
|
||||
|
||||
st, ok := status.FromError(err)
|
||||
if !ok {
|
||||
logger.Fatal("received unexpected error", zap.Error(err))
|
||||
}
|
||||
|
||||
var violations []string
|
||||
for _, detail := range st.Details() {
|
||||
switch d := detail.(type) {
|
||||
case *errdetails.BadRequest:
|
||||
for _, violation := range d.GetFieldViolations() {
|
||||
violations = append(violations, violation.GetField()+": "+violation.GetDescription())
|
||||
}
|
||||
default:
|
||||
logger.Debug("unhandled detail", zap.Any("detail", d))
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("received error", zap.Error(err), zap.Strings("violations", violations))
|
||||
}
|
||||
|
||||
const (
|
||||
namesLen = 20
|
||||
)
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||
grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
@ -156,6 +157,31 @@ func (g *greeterServer) SayHello(_ context.Context, r *proto.HelloRequest) (*pro
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (g *greeterServer) SayHelloToJames(_ context.Context, r *proto.HelloRequest) (*proto.HelloReply, error) {
|
||||
name := r.GetName()
|
||||
|
||||
if name != "James" {
|
||||
st, err := status.
|
||||
New(codes.InvalidArgument, "invalid name").
|
||||
WithDetails(&errdetails.BadRequest{
|
||||
FieldViolations: []*errdetails.BadRequest_FieldViolation{
|
||||
{
|
||||
Field: "name",
|
||||
Description: "must be James",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.New(codes.Internal, "internal server error").Err()
|
||||
}
|
||||
return nil, st.Err()
|
||||
}
|
||||
|
||||
return &proto.HelloReply{
|
||||
Message: buildHelloMsg(name),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g *greeterServer) SayHelloServerStream(r *proto.MultiHelloRequest, stream proto.Greeter_SayHelloServerStreamServer) error {
|
||||
for _, n := range r.GetNames() {
|
||||
if err := stream.Send(&proto.HelloReply{
|
||||
|
|
|
@ -4,6 +4,7 @@ option go_package = "gitea.dwysokinski.me/Kichiyaki/grpc-g2a/proto";
|
|||
|
||||
service Greeter {
|
||||
rpc SayHello (HelloRequest) returns (HelloReply) {}
|
||||
rpc SayHelloToJames (HelloRequest) returns (HelloReply) {}
|
||||
rpc SayHelloClientStream (stream HelloRequest) returns (MultiHelloReply) {}
|
||||
rpc SayHelloServerStream (MultiHelloRequest) returns (stream HelloReply) {}
|
||||
rpc SayHelloBidirectionalStream (stream HelloRequest) returns (stream HelloReply) {}
|
||||
|
|
Loading…
Reference in New Issue