package middleware import ( "net/http" "runtime/debug" "git.threesix.ai/jordan/slack-q-1770281596/pkg/httpcontext" "git.threesix.ai/jordan/slack-q-1770281596/pkg/logging" ) // Recoverer is middleware that recovers from panics, logs the error with stack trace // using slog, and returns a 500 Internal Server Error response. // // The middleware captures: // - request_id: For request correlation // - method, path, remote_addr: Request context // - panic: The recovered panic value // - stack_trace: Full stack trace for debugging // // Usage: // // r.Use(middleware.RequestID()) // r.Use(middleware.RequestLogger(logger)) // r.Use(middleware.Recoverer(logger)) func Recoverer(logger *logging.Logger) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { defer func() { if rvr := recover(); rvr != nil { // Capture stack trace for debugging stack := debug.Stack() // Get request ID from context requestID, _ := httpcontext.GetRequestID(r.Context()) // Log panic with full context and stack trace logger.Error("panic recovered", "request_id", requestID, "method", r.Method, "path", r.URL.Path, "remote_addr", r.RemoteAddr, "panic", rvr, "stack_trace", string(stack), ) // Return 500 Internal Server Error to client http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) } }() next.ServeHTTP(w, r) }) } }