package gin import ( "fmt" "net" "net/http" "os" "runtime/debug" "strings" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "gitlab.com/dotpe/mindbenders/logging" ) // Recovery returns a gin.HandlerFunc having recovery solution func Recovery(l logging.ILogWriter) gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err := recover(); err != nil { stack := fmt.Sprintf("%v\n%s", err, debug.Stack()) //copied from /usr/local/go/src/runtime/debug/stack.go | gin@v1.6.3 if ne, ok := err.(*net.OpError); ok { if se, ok := ne.Err.(*os.SyscallError); ok { if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") { c.Error(err.(error)) // nolint: errcheck c.Abort() l.WriteLogs(c, logrus.Fields{"stacktrace": stack}, logging.FatalLevel, "BrokenPipe") return } } } l.WriteLogs(c, logrus.Fields{"stacktrace": stack}, logging.FatalLevel, "Panic") c.JSON(http.StatusExpectationFailed, map[string]interface{}{ "message": "something went wrong", "status": false, }) } }() c.Next() } }