mirror of
https://github.com/Fishwaldo/huma.git
synced 2025-03-15 19:31:27 +00:00
feat: custom recovery middleware
This commit is contained in:
parent
5b12909537
commit
92422ae10d
4 changed files with 65 additions and 4 deletions
|
@ -531,9 +531,9 @@ r := huma.NewRouter(&huma.OpenAPI{
|
|||
|
||||
// For this:
|
||||
g := gin.New()
|
||||
g.Use(gin.Recovery())
|
||||
g.Use(cors.Default())
|
||||
g.Use(huma.Recovery())
|
||||
g.Use(huma.LogMiddleware(nil, nil))
|
||||
g.Use(cors.Default())
|
||||
r := huma.NewRouterWithGin(g, &huma.OpenAPI{
|
||||
Title: "Notes API",
|
||||
Version: "1.0.0",
|
||||
|
|
|
@ -2,6 +2,7 @@ package huma
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
|
@ -13,6 +14,26 @@ import (
|
|||
|
||||
var logLevel *zap.AtomicLevel
|
||||
|
||||
// Recovery prints stack traces on panic when used with the logging middleware.
|
||||
func Recovery() func(*gin.Context) {
|
||||
return func(c *gin.Context) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
if l, ok := c.Get("log"); ok {
|
||||
if log, ok := l.(*zap.SugaredLogger); ok {
|
||||
log.With(zap.Error(err.(error))).Error("Caught panic")
|
||||
}
|
||||
}
|
||||
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, &ErrorModel{
|
||||
Message: "Internal server error",
|
||||
})
|
||||
}
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// NewLogger returns a new low-level `*zap.Logger` instance. If the current
|
||||
// terminal is a TTY, it will try ot use colored output automatically.
|
||||
func NewLogger() (*zap.Logger, error) {
|
||||
|
|
40
middleware_test.go
Normal file
40
middleware_test.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package huma
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/zap/zaptest"
|
||||
)
|
||||
|
||||
func TestRecoveryMiddleware(t *testing.T) {
|
||||
g := gin.New()
|
||||
|
||||
l := zaptest.NewLogger(t)
|
||||
g.Use(LogMiddleware(l, nil))
|
||||
g.Use(Recovery())
|
||||
|
||||
r := NewRouterWithGin(g, &OpenAPI{Title: "My API", Version: "1.0.0"})
|
||||
|
||||
r.Register(&Operation{
|
||||
Method: http.MethodGet,
|
||||
Path: "/panic",
|
||||
Description: "Panic recovery test",
|
||||
Responses: []*Response{
|
||||
ResponseText(http.StatusOK, "Success"),
|
||||
},
|
||||
Handler: func() string {
|
||||
panic(fmt.Errorf("Some error"))
|
||||
},
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, "/panic", nil)
|
||||
r.ServeHTTP(w, req)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Equal(t, "application/json; charset=utf-8", w.Result().Header.Get("content-type"))
|
||||
}
|
|
@ -171,9 +171,9 @@ type Router struct {
|
|||
// CORS (allowing all origins), and log middlewares.
|
||||
func NewRouter(api *OpenAPI) *Router {
|
||||
g := gin.New()
|
||||
g.Use(gin.Recovery())
|
||||
g.Use(cors.Default())
|
||||
g.Use(Recovery())
|
||||
g.Use(LogMiddleware(nil, nil))
|
||||
g.Use(cors.Default())
|
||||
return NewRouterWithGin(g, api)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue