Files
go-common/middleware/recovery.go

48 lines
1.3 KiB
Go

package middleware
import (
"fmt"
"net/http"
"runtime/debug"
commonhttp "git.toowon.com/jimmy/go-common/http"
"git.toowon.com/jimmy/go-common/i18n"
"git.toowon.com/jimmy/go-common/logger"
)
// RecoveryConfig Recovery 中间件配置
type RecoveryConfig struct {
Logger *logger.Logger
I18n *i18n.I18n
}
// Recovery Panic 恢复中间件,响应统一 JSON 200 + system.internal_error
func Recovery(config *RecoveryConfig) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
fields := map[string]any{
"method": r.Method,
"path": r.URL.Path,
"error": fmt.Sprintf("%v", err),
"stack": string(debug.Stack()),
}
log := logger.FromContextWithLogger(r.Context(), nil)
if config != nil && config.Logger != nil {
log = logger.FromContextWithLogger(r.Context(), config.Logger)
}
log.Error("panic recovered", fields)
h := commonhttp.NewHandler(w, r)
if config != nil && config.I18n != nil {
h = commonhttp.NewHandler(w, r, commonhttp.WithI18n(config.I18n))
}
h.Error("system.internal_error")
}
}()
next.ServeHTTP(w, r)
})
}
}