1
0
mirror of https://github.com/go-kratos/kratos.git synced 2025-01-10 00:29:01 +02:00
kratos/pkg/net/rpc/warden/recovery.go
longxboy 637a6a3628 add warden rpc (#9)
* add warden rpc
2019-04-12 17:32:10 +08:00

62 lines
1.6 KiB
Go

package warden
import (
"context"
"fmt"
"os"
"runtime"
"github.com/bilibili/kratos/pkg/ecode"
"github.com/bilibili/kratos/pkg/log"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// recovery is a server interceptor that recovers from any panics.
func (s *Server) recovery() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, args *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
defer func() {
if rerr := recover(); rerr != nil {
const size = 64 << 10
buf := make([]byte, size)
rs := runtime.Stack(buf, false)
if rs > size {
rs = size
}
buf = buf[:rs]
pl := fmt.Sprintf("grpc server panic: %v\n%v\n%s\n", req, rerr, buf)
fmt.Fprintf(os.Stderr, pl)
log.Error(pl)
err = status.Errorf(codes.Unknown, ecode.ServerErr.Error())
}
}()
resp, err = handler(ctx, req)
return
}
}
// recovery return a client interceptor that recovers from any panics.
func (c *Client) recovery() grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) (err error) {
defer func() {
if rerr := recover(); rerr != nil {
const size = 64 << 10
buf := make([]byte, size)
rs := runtime.Stack(buf, false)
if rs > size {
rs = size
}
buf = buf[:rs]
pl := fmt.Sprintf("grpc client panic: %v\n%v\n%v\n%s\n", req, reply, rerr, buf)
fmt.Fprintf(os.Stderr, pl)
log.Error(pl)
err = ecode.ServerErr
}
}()
err = invoker(ctx, method, req, reply, cc, opts...)
return
}
}