matterbridge/vendor/github.com/labstack/echo/v4/middleware/recover.go

135 lines
3.6 KiB
Go
Raw Normal View History

2017-02-18 14:00:46 -08:00
package middleware
import (
"fmt"
2022-03-31 15:23:19 -07:00
"net/http"
2017-02-18 14:00:46 -08:00
"runtime"
"github.com/labstack/echo/v4"
2020-09-04 14:29:13 -07:00
"github.com/labstack/gommon/log"
2017-02-18 14:00:46 -08:00
)
type (
2022-03-12 10:41:07 -08:00
// LogErrorFunc defines a function for custom logging in the middleware.
LogErrorFunc func(c echo.Context, err error, stack []byte) error
2017-02-18 14:00:46 -08:00
// RecoverConfig defines the config for Recover middleware.
RecoverConfig struct {
// Skipper defines a function to skip middleware.
Skipper Skipper
// Size of the stack to be printed.
// Optional. Default value 4KB.
2018-02-20 15:48:10 -08:00
StackSize int `yaml:"stack_size"`
2017-02-18 14:00:46 -08:00
// DisableStackAll disables formatting stack traces of all other goroutines
// into buffer after the trace for the current goroutine.
// Optional. Default value false.
2018-02-20 15:48:10 -08:00
DisableStackAll bool `yaml:"disable_stack_all"`
2017-02-18 14:00:46 -08:00
// DisablePrintStack disables printing stack trace.
// Optional. Default value as false.
2018-02-20 15:48:10 -08:00
DisablePrintStack bool `yaml:"disable_print_stack"`
2020-09-04 14:29:13 -07:00
// LogLevel is log level to printing stack trace.
// Optional. Default value 0 (Print).
LogLevel log.Lvl
2022-03-12 10:41:07 -08:00
// LogErrorFunc defines a function for custom logging in the middleware.
// If it's set you don't need to provide LogLevel for config.
// If this function returns nil, the centralized HTTPErrorHandler will not be called.
2022-03-12 10:41:07 -08:00
LogErrorFunc LogErrorFunc
// DisableErrorHandler disables the call to centralized HTTPErrorHandler.
// The recovered error is then passed back to upstream middleware, instead of swallowing the error.
// Optional. Default value false.
DisableErrorHandler bool `yaml:"disable_error_handler"`
2017-02-18 14:00:46 -08:00
}
)
var (
// DefaultRecoverConfig is the default Recover middleware config.
DefaultRecoverConfig = RecoverConfig{
Skipper: DefaultSkipper,
StackSize: 4 << 10, // 4 KB
DisableStackAll: false,
DisablePrintStack: false,
LogLevel: 0,
LogErrorFunc: nil,
DisableErrorHandler: false,
2017-02-18 14:00:46 -08:00
}
)
// Recover returns a middleware which recovers from panics anywhere in the chain
// and handles the control to the centralized HTTPErrorHandler.
func Recover() echo.MiddlewareFunc {
return RecoverWithConfig(DefaultRecoverConfig)
}
// RecoverWithConfig returns a Recover middleware with config.
// See: `Recover()`.
func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc {
// Defaults
if config.Skipper == nil {
config.Skipper = DefaultRecoverConfig.Skipper
}
if config.StackSize == 0 {
config.StackSize = DefaultRecoverConfig.StackSize
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) (returnErr error) {
2017-02-18 14:00:46 -08:00
if config.Skipper(c) {
return next(c)
}
defer func() {
if r := recover(); r != nil {
2022-03-31 15:23:19 -07:00
if r == http.ErrAbortHandler {
panic(r)
}
2017-12-07 14:00:56 -08:00
err, ok := r.(error)
if !ok {
2017-02-18 14:00:46 -08:00
err = fmt.Errorf("%v", r)
}
2022-03-12 10:41:07 -08:00
var stack []byte
var length int
2017-02-18 14:00:46 -08:00
if !config.DisablePrintStack {
2022-03-12 10:41:07 -08:00
stack = make([]byte, config.StackSize)
length = runtime.Stack(stack, !config.DisableStackAll)
stack = stack[:length]
}
if config.LogErrorFunc != nil {
err = config.LogErrorFunc(c, err, stack)
} else if !config.DisablePrintStack {
2020-09-04 14:29:13 -07:00
msg := fmt.Sprintf("[PANIC RECOVER] %v %s\n", err, stack[:length])
switch config.LogLevel {
case log.DEBUG:
c.Logger().Debug(msg)
case log.INFO:
c.Logger().Info(msg)
case log.WARN:
c.Logger().Warn(msg)
case log.ERROR:
c.Logger().Error(msg)
case log.OFF:
// None.
default:
c.Logger().Print(msg)
}
2017-02-18 14:00:46 -08:00
}
if err != nil && !config.DisableErrorHandler {
c.Error(err)
} else {
returnErr = err
}
2017-02-18 14:00:46 -08:00
}
}()
return next(c)
}
}
}