recover middleware support print stack trace

pull/1131/head
bluetian 2021-01-23 12:11:42 +08:00 committed by tianjipeng
parent ba7fc034c2
commit 5adafe2ecb
4 changed files with 59 additions and 2 deletions

View File

@ -41,12 +41,24 @@ type Config struct {
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool
// EnableStackTrace enables handling stack trace
//
// Optional. Default: false
EnableStackTrace bool
// StackTraceHandler defines a function to handle stack trace
//
// Optional. Default: defaultStackTraceHandler
StackTraceHandler func(e interface{})
}
```
### Default Config
```go
var ConfigDefault = Config{
Next: nil,
Next: nil,
EnableStackTrace: false,
StackTraceHandler: defaultStackTraceHandler,
}
```

View File

@ -10,11 +10,25 @@ type Config struct {
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool
// EnableStackTrace enables handling stack trace
//
// Optional. Default: false
EnableStackTrace bool
// StackTraceHandler defines a function to handle stack trace
//
// Optional. Default: defaultStackTraceHandler
StackTraceHandler func(e interface{})
}
var defaultStackTraceBufLen = 1024
// ConfigDefault is the default config
var ConfigDefault = Config{
Next: nil,
Next: nil,
EnableStackTrace: false,
StackTraceHandler: defaultStackTraceHandler,
}
// Helper function to set default values
@ -27,5 +41,9 @@ func configDefault(config ...Config) Config {
// Override default config
cfg := config[0]
if cfg.EnableStackTrace && cfg.StackTraceHandler == nil {
cfg.StackTraceHandler = defaultStackTraceHandler
}
return cfg
}

View File

@ -2,10 +2,18 @@ package recover
import (
"fmt"
"os"
"runtime"
"github.com/gofiber/fiber/v2"
)
func defaultStackTraceHandler(e interface{}) {
buf := make([]byte, defaultStackTraceBufLen)
buf = buf[:runtime.Stack(buf, false)]
_, _ = os.Stderr.WriteString(fmt.Sprintf("panic: %v\n%s\n", e, buf))
}
// New creates a new middleware handler
func New(config ...Config) fiber.Handler {
// Set default config
@ -21,6 +29,10 @@ func New(config ...Config) fiber.Handler {
// Catch panics
defer func() {
if r := recover(); r != nil {
if cfg.EnableStackTrace {
cfg.StackTraceHandler(r)
}
var ok bool
if err, ok = r.(error); !ok {
// Set error that will call the global error handler

View File

@ -41,3 +41,18 @@ func Test_Recover_Next(t *testing.T) {
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusNotFound, resp.StatusCode)
}
func Test_Recover_EnableStackTrace(t *testing.T) {
app := fiber.New()
app.Use(New(Config{
EnableStackTrace: true,
}))
app.Get("/panic", func(c *fiber.Ctx) error {
panic("Hi, I'm an error!")
})
resp, err := app.Test(httptest.NewRequest("GET", "/panic", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, fiber.StatusInternalServerError, resp.StatusCode)
}