Skip to content

Commit

Permalink
feat: Add recovery middleware for GRPC server
Browse files Browse the repository at this point in the history
  • Loading branch information
laynax committed Jun 18, 2024
1 parent bcfe1b2 commit fe7c3a3
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
42 changes: 42 additions & 0 deletions pkg/interceptors/recovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package interceptors

import (
"context"
stdlog "log"
"runtime/debug"
"time"

"github.com/getsentry/sentry-go"
grpcrecovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

sdkloggercontext "github.com/scribd/go-sdk/pkg/context/logger"
)

var recoveryOption = []grpcrecovery.Option{
grpcrecovery.WithRecoveryHandlerContext(func(ctx context.Context, rec interface{}) (err error) {
sentry.CurrentHub().Recover(rec)
sentry.Flush(time.Second * 5)

l, err := sdkloggercontext.Extract(ctx)
if err != nil {
debug.PrintStack()
stdlog.Printf("logger not found in context: %v\n", err)
stdlog.Fatalf("panic error: %v", rec)
}

l.Fatalf("panic error: %v", rec)
return status.Errorf(codes.Internal, "")
}),
}

// cmnt us
func RecoveryUnaryServerInterceptor() grpc.UnaryServerInterceptor {
return grpcrecovery.UnaryServerInterceptor(recoveryOption...)
}

func RecoveryStreamServerInterceptor() grpc.StreamServerInterceptor {
return grpcrecovery.StreamServerInterceptor(recoveryOption...)
}
40 changes: 40 additions & 0 deletions pkg/middleware/recovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package middleware

import (
"log"
"net/http"
"runtime/debug"
"time"

"github.com/getsentry/sentry-go"
sdkloggercontext "github.com/scribd/go-sdk/pkg/context/logger"
)

type RecoveryMiddleware struct{}

func NewRecoveryMiddleware() RecoveryMiddleware {
return RecoveryMiddleware{}
}

// cmnt us
func (rm RecoveryMiddleware) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
sentry.CurrentHub().Recover(rec)
sentry.Flush(time.Second * 5)

l, err := sdkloggercontext.Extract(r.Context())
if err != nil {
debug.PrintStack()
log.Printf("logger not found in context: %v\n", err)
log.Fatalf("http: panic serving URI %s: %v", r.URL.RequestURI(), rec)
}

l.Fatalf("http: panic serving URI %s: %v", r.URL.RequestURI(), rec)
}
}()

next.ServeHTTP(w, r)
})
}

0 comments on commit fe7c3a3

Please sign in to comment.