package middleware import ( "net" "net/http" "net/http/httputil" "os" "runtime/debug" "strings" "modelRT/logger" "github.com/gin-gonic/gin" ) // GinPanicRecovery define func of customizing gin recover output func GinPanicRecovery() gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // Check for a broken connection, as it is not really a // condition that warrants a panic stack trace. var brokenPipe bool 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") { brokenPipe = true } } } httpRequest, _ := httputil.DumpRequest(c.Request, false) if brokenPipe { logger.Error(c, "http request broken pipe", "path", c.Request.URL.Path, "error", err, "request", string(httpRequest)) // If the connection is dead, we can't write a status to it. c.Error(err.(error)) c.Abort() return } logger.Error(c, "http_request_panic", "path", c.Request.URL.Path, "error", err, "request", string(httpRequest), "stack", string(debug.Stack())) c.AbortWithError(http.StatusInternalServerError, err.(error)) } }() c.Next() } }