Recovery returns a middleware that recovers from panics. For /api routes, returns JSON so piped install scripts don't execute error text as shell commands.
(log *slog.Logger)
| 11 | // Recovery returns a middleware that recovers from panics. |
| 12 | // For /api routes, returns JSON so piped install scripts don't execute error text as shell commands. |
| 13 | func Recovery(log *slog.Logger) func(http.Handler) http.Handler { |
| 14 | return func(next http.Handler) http.Handler { |
| 15 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 16 | defer func() { |
| 17 | if err := recover(); err != nil { |
| 18 | log.Error("panic recovered", |
| 19 | "error", err, |
| 20 | "path", r.URL.Path, |
| 21 | "method", r.Method, |
| 22 | "stack", string(debug.Stack())) |
| 23 | if strings.HasPrefix(r.URL.Path, "/api") { |
| 24 | w.Header().Set("Content-Type", "application/json") |
| 25 | w.WriteHeader(http.StatusInternalServerError) |
| 26 | _ = json.NewEncoder(w).Encode(map[string]string{"error": "Internal Server Error"}) |
| 27 | } else { |
| 28 | http.Error(w, "Internal Server Error", http.StatusInternalServerError) |
| 29 | } |
| 30 | } |
| 31 | }() |
| 32 | next.ServeHTTP(w, r) |
| 33 | }) |
| 34 | } |
| 35 | } |