github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/http/fast/middleware/recover/recover.go (about)

     1  package recover
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/angenalZZZ/gofunc/http/fast"
     6  	"github.com/angenalZZZ/gofunc/log"
     7  )
     8  
     9  // Config defines the config for recover middleware
    10  type Config struct {
    11  	// Filter defines a function to skip middleware.
    12  	// Optional. Default: nil
    13  	Filter func(*fast.Ctx) bool
    14  	// Handler is called when a panic occurs
    15  	// Optional. Default: c.SendStatus(500)
    16  	Handler func(*fast.Ctx, error)
    17  	// Log all errors to output
    18  	// Optional. Default: false
    19  	Log bool
    20  	// Output is a writer where logs are written
    21  	// Default: log.Log
    22  	Output *log.Logger
    23  }
    24  
    25  // New middleware.
    26  // cfg := recover.Config{
    27  //     Log: true,
    28  //     Handler: func(c *fast.Ctx, err error) {
    29  //         c.SendString(err.Error())
    30  //         c.SendStatus(500)
    31  //     },
    32  // }
    33  // app.Use(recover.New(cfg))
    34  func New(config ...Config) func(*fast.Ctx) {
    35  	// Init config
    36  	var cfg Config
    37  	// SetHeader config if provided
    38  	if len(config) > 0 {
    39  		cfg = config[0]
    40  	}
    41  	// SetHeader config default values
    42  	if cfg.Handler == nil {
    43  		cfg.Handler = func(c *fast.Ctx, err error) {
    44  			c.SendString("unknown error")
    45  			c.SendStatus(500)
    46  		}
    47  	}
    48  	if cfg.Output == nil {
    49  		cfg.Output = log.Log
    50  	}
    51  	// Return middleware handle
    52  	return func(c *fast.Ctx) {
    53  		// Filter request to skip middleware
    54  		if cfg.Filter != nil && cfg.Filter(c) {
    55  			c.Next()
    56  			return
    57  		}
    58  		defer func() {
    59  			if r := recover(); r != nil {
    60  				err, ok := r.(error)
    61  				if !ok {
    62  					err = fmt.Errorf("%v", r)
    63  				}
    64  				if cfg.Log && cfg.Output != nil {
    65  					cfg.Output.Err(err).Send()
    66  				}
    67  				cfg.Handler(c, err)
    68  			}
    69  		}()
    70  		c.Next()
    71  	}
    72  }