mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 20:30:51 +08:00
test(logging): add unit tests for GinLogrusRecovery middleware panic handling
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
@@ -112,6 +113,11 @@ func isAIAPIPath(path string) bool {
|
|||||||
// - gin.HandlerFunc: A middleware handler for panic recovery
|
// - gin.HandlerFunc: A middleware handler for panic recovery
|
||||||
func GinLogrusRecovery() gin.HandlerFunc {
|
func GinLogrusRecovery() gin.HandlerFunc {
|
||||||
return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
|
return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
|
||||||
|
if err, ok := recovered.(error); ok && errors.Is(err, http.ErrAbortHandler) {
|
||||||
|
// Let net/http handle ErrAbortHandler so the connection is aborted without noisy stack logs.
|
||||||
|
panic(http.ErrAbortHandler)
|
||||||
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"panic": recovered,
|
"panic": recovered,
|
||||||
"stack": string(debug.Stack()),
|
"stack": string(debug.Stack()),
|
||||||
|
|||||||
60
internal/logging/gin_logger_test.go
Normal file
60
internal/logging/gin_logger_test.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package logging
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGinLogrusRecoveryRepanicsErrAbortHandler(t *testing.T) {
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
|
||||||
|
engine := gin.New()
|
||||||
|
engine.Use(GinLogrusRecovery())
|
||||||
|
engine.GET("/abort", func(c *gin.Context) {
|
||||||
|
panic(http.ErrAbortHandler)
|
||||||
|
})
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/abort", nil)
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
recovered := recover()
|
||||||
|
if recovered == nil {
|
||||||
|
t.Fatalf("expected panic, got nil")
|
||||||
|
}
|
||||||
|
err, ok := recovered.(error)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected error panic, got %T", recovered)
|
||||||
|
}
|
||||||
|
if !errors.Is(err, http.ErrAbortHandler) {
|
||||||
|
t.Fatalf("expected ErrAbortHandler, got %v", err)
|
||||||
|
}
|
||||||
|
if err != http.ErrAbortHandler {
|
||||||
|
t.Fatalf("expected exact ErrAbortHandler sentinel, got %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
engine.ServeHTTP(recorder, req)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGinLogrusRecoveryHandlesRegularPanic(t *testing.T) {
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
|
||||||
|
engine := gin.New()
|
||||||
|
engine.Use(GinLogrusRecovery())
|
||||||
|
engine.GET("/panic", func(c *gin.Context) {
|
||||||
|
panic("boom")
|
||||||
|
})
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/panic", nil)
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
|
||||||
|
engine.ServeHTTP(recorder, req)
|
||||||
|
if recorder.Code != http.StatusInternalServerError {
|
||||||
|
t.Fatalf("expected 500, got %d", recorder.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user