48 lines
1.3 KiB
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)
|
|
})
|
|
}
|
|
}
|