82 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package middleware
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"runtime"
 | |
| 
 | |
| 	"github.com/labstack/echo"
 | |
| )
 | |
| 
 | |
| type (
 | |
| 	// 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.
 | |
| 		StackSize int `json:"stack_size"`
 | |
| 
 | |
| 		// DisableStackAll disables formatting stack traces of all other goroutines
 | |
| 		// into buffer after the trace for the current goroutine.
 | |
| 		// Optional. Default value false.
 | |
| 		DisableStackAll bool `json:"disable_stack_all"`
 | |
| 
 | |
| 		// DisablePrintStack disables printing stack trace.
 | |
| 		// Optional. Default value as false.
 | |
| 		DisablePrintStack bool `json:"disable_print_stack"`
 | |
| 	}
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// DefaultRecoverConfig is the default Recover middleware config.
 | |
| 	DefaultRecoverConfig = RecoverConfig{
 | |
| 		Skipper:           DefaultSkipper,
 | |
| 		StackSize:         4 << 10, // 4 KB
 | |
| 		DisableStackAll:   false,
 | |
| 		DisablePrintStack: false,
 | |
| 	}
 | |
| )
 | |
| 
 | |
| // 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 {
 | |
| 					err, ok := r.(error)
 | |
| 					if !ok {
 | |
| 						err = fmt.Errorf("%v", r)
 | |
| 					}
 | |
| 					stack := make([]byte, config.StackSize)
 | |
| 					length := runtime.Stack(stack, !config.DisableStackAll)
 | |
| 					if !config.DisablePrintStack {
 | |
| 						c.Logger().Printf("[PANIC RECOVER] %v %s\n", err, stack[:length])
 | |
| 					}
 | |
| 					c.Error(err)
 | |
| 				}
 | |
| 			}()
 | |
| 			return next(c)
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
