5
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2024-11-24 19:01:55 +00:00
matterbridge/vendor/github.com/labstack/echo/v4/middleware/recover.go

123 lines
3.1 KiB
Go
Raw Normal View History

2017-02-18 22:00:46 +00:00
package middleware
import (
"fmt"
2022-03-31 22:23:19 +00:00
"net/http"
2017-02-18 22:00:46 +00:00
"runtime"
"github.com/labstack/echo/v4"
2020-09-04 21:29:13 +00:00
"github.com/labstack/gommon/log"
2017-02-18 22:00:46 +00:00
)
type (
2022-03-12 18:41:07 +00:00
// LogErrorFunc defines a function for custom logging in the middleware.
LogErrorFunc func(c echo.Context, err error, stack []byte) error
2017-02-18 22:00:46 +00: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 23:48:10 +00:00
StackSize int `yaml:"stack_size"`
2017-02-18 22:00:46 +00: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 23:48:10 +00:00
DisableStackAll bool `yaml:"disable_stack_all"`
2017-02-18 22:00:46 +00:00
// DisablePrintStack disables printing stack trace.
// Optional. Default value as false.
2018-02-20 23:48:10 +00:00
DisablePrintStack bool `yaml:"disable_print_stack"`
2020-09-04 21:29:13 +00:00
// LogLevel is log level to printing stack trace.
// Optional. Default value 0 (Print).
LogLevel log.Lvl
2022-03-12 18:41:07 +00:00
// LogErrorFunc defines a function for custom logging in the middleware.
// If it's set you don't need to provide LogLevel for config.
LogErrorFunc LogErrorFunc
2017-02-18 22:00:46 +00:00
}
)
var (
// DefaultRecoverConfig is the default Recover middleware config.
DefaultRecoverConfig = RecoverConfig{
Skipper: DefaultSkipper,
StackSize: 4 << 10, // 4 KB
DisableStackAll: false,
DisablePrintStack: false,
2020-09-04 21:29:13 +00:00
LogLevel: 0,
2022-03-12 18:41:07 +00:00
LogErrorFunc: nil,
2017-02-18 22:00:46 +00: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) error {
if config.Skipper(c) {
return next(c)
}
defer func() {
if r := recover(); r != nil {
2022-03-31 22:23:19 +00:00
if r == http.ErrAbortHandler {
panic(r)
}
2017-12-07 22:00:56 +00:00
err, ok := r.(error)
if !ok {
2017-02-18 22:00:46 +00:00
err = fmt.Errorf("%v", r)
}
2022-03-12 18:41:07 +00:00
var stack []byte
var length int
2017-02-18 22:00:46 +00:00
if !config.DisablePrintStack {
2022-03-12 18:41:07 +00: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 21:29:13 +00: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 22:00:46 +00:00
}
c.Error(err)
}
}()
return next(c)
}
}
}