32 lines
890 B
Go
32 lines
890 B
Go
package middleware
|
||
|
||
import (
|
||
"log/slog"
|
||
"net/http"
|
||
"runtime/debug"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// Recovery перехватывает панику в хендлере: клиент получает честный
|
||
// 500 с фиксированным текстом, а в лог уходят причина и стек —
|
||
// стек наружу не уходит, но без него панику не воспроизвести.
|
||
func Recovery() gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
defer func() {
|
||
if rec := recover(); rec != nil {
|
||
slog.Error("panic recovered",
|
||
"error", rec,
|
||
"request_id", RequestIDFrom(c),
|
||
"method", c.Request.Method,
|
||
"path", c.Request.URL.Path,
|
||
"stack", string(debug.Stack()),
|
||
)
|
||
c.AbortWithStatusJSON(http.StatusInternalServerError,
|
||
gin.H{"error": "internal server error"})
|
||
}
|
||
}()
|
||
c.Next()
|
||
}
|
||
}
|