You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.6 KiB
61 lines
1.6 KiB
package warden
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
|
|
"github.com/go-kratos/kratos/pkg/ecode"
|
|
"github.com/go-kratos/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
|
|
}
|
|
}
|
|
|