package ginutils import ( "fmt" "runtime/debug" "strings" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) // Recovery will catch a panic and : // - Recover // - log the stacktrace. func Recovery(handler gin.HandlerFunc) gin.HandlerFunc { if handler == nil { handler = func(c *gin.Context) { c.AbortWithStatusJSON(500, map[string]string{ "message": "Internal Server Error", "debugId": c.GetString(string(ContextKey_RequestID)), }) } } return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // log the error log := GetLoggerWithFields(c, logrus.Fields{ "error": err, "stacktrace": fmt.Sprintf("%v\n%s", err, getStacktrace()), }) if log != nil { log.Error("A Panic happened and has been caught") } handler(c) } }() c.Next() gin.Recovery() } } func getStacktrace() 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") }