feat(middlewares): Add stacktrace in recovery log
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@ -3,8 +3,11 @@ package middleware
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"git.dev.m-and-m.ovh/mderasse/gocommon/commonctx"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type recoveryFuncSignature func(w http.ResponseWriter, r *http.Request)
|
||||
@ -17,13 +20,14 @@ type recoveryMiddleware struct {
|
||||
func (rm *recoveryMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
|
||||
// log the error
|
||||
log := commonctx.GetLogger(r.Context())
|
||||
log := commonctx.GetLoggerWithFields(r.Context(), logrus.Fields{
|
||||
"error": err,
|
||||
"stacktrace": fmt.Sprintf("%v\n%s", err, getStackrace()),
|
||||
})
|
||||
if log == nil {
|
||||
fmt.Print("Impossible to log the panic as the logger is not part of the context\n")
|
||||
} else {
|
||||
// Probably have to catch a stacktrace + Info about the error
|
||||
log.Error("A Panic happened and has been caught")
|
||||
}
|
||||
// execute the recovery function
|
||||
@ -33,9 +37,15 @@ func (rm *recoveryMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
rm.handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func getStackrace() string {
|
||||
stackLines := strings.Split(string(debug.Stack()), "\n")
|
||||
// removing a few first line as they are either that function or the middleware
|
||||
return strings.Join(stackLines[9:], "\n")
|
||||
}
|
||||
|
||||
// NewRecoveryMiddleware will declare a new middleware on the provided handler. It will recover any panic and log it.
|
||||
// By default, the middleware will return a default error object in json with a 500 Http code. That can be overide by providing a recoveryFunc.
|
||||
func NewRecoveryMiddleware(h http.Handler, recoveryFunc recoveryFuncSignature) *recoveryMiddleware {
|
||||
func NewRecoveryMiddleware(h http.Handler, recoveryFunc recoveryFuncSignature) http.Handler {
|
||||
recovery := &recoveryMiddleware{
|
||||
handler: h,
|
||||
respFunc: recoveryFunc,
|
||||
|
Reference in New Issue
Block a user