sync from project
This commit is contained in:
@ -42,3 +42,20 @@ func DebugPanicHandler(w http.ResponseWriter, r *http.Request, err any) {
|
||||
func Debug() middleware.Middleware {
|
||||
return Recover(DebugPanicHandler)
|
||||
}
|
||||
|
||||
// ProductionPanicHandler is a PanicResponseFunc that provides a generic error message
|
||||
// in production environments and logs the detailed panic error.
|
||||
func ProductionPanicHandler(w http.ResponseWriter, r *http.Request, err any) {
|
||||
httplog.Logger(r).With("panic", err).Error("request panicked")
|
||||
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]any{
|
||||
"error": "Internal Server Error",
|
||||
})
|
||||
}
|
||||
|
||||
// Production returns a middleware that recovers from panics and handles them
|
||||
// with ProductionPanicHandler.
|
||||
func Production() middleware.Middleware {
|
||||
return Recover(ProductionPanicHandler)
|
||||
}
|
||||
|
56
middleware/recover/recover_test.go
Normal file
56
middleware/recover/recover_test.go
Normal file
@ -0,0 +1,56 @@
|
||||
package recover
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func panicHandler(w http.ResponseWriter, r *http.Request) {
|
||||
panic("test panic")
|
||||
}
|
||||
|
||||
func TestDebugRecover(t *testing.T) {
|
||||
handler := http.HandlerFunc(panicHandler)
|
||||
wrappedHandler := Debug().WrapHandler(handler)
|
||||
|
||||
req := httptest.NewRequest("GET", "/panic", nil)
|
||||
rr := httptest.NewRecorder()
|
||||
wrappedHandler.ServeHTTP(rr, req)
|
||||
|
||||
if rr.Code != http.StatusInternalServerError {
|
||||
t.Errorf("expected status %d, got %d", http.StatusInternalServerError, rr.Code)
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to unmarshal response body: %v", err)
|
||||
}
|
||||
|
||||
if resp["error"] != "test panic" {
|
||||
t.Errorf("expected error 'test panic', got '%v'", resp["error"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestProductionRecover(t *testing.T) {
|
||||
handler := http.HandlerFunc(panicHandler)
|
||||
wrappedHandler := Production().WrapHandler(handler)
|
||||
|
||||
req := httptest.NewRequest("GET", "/panic", nil)
|
||||
rr := httptest.NewRecorder()
|
||||
wrappedHandler.ServeHTTP(rr, req)
|
||||
|
||||
if rr.Code != http.StatusInternalServerError {
|
||||
t.Errorf("expected status %d, got %d", http.StatusInternalServerError, rr.Code)
|
||||
}
|
||||
|
||||
var resp map[string]any
|
||||
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
||||
t.Fatalf("failed to unmarshal response body: %v", err)
|
||||
}
|
||||
|
||||
if resp["error"] != "Internal Server Error" {
|
||||
t.Errorf("expected error 'Internal Server Error', got '%v'", resp["error"])
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user