package negroni import ( "fmt" "log" "net/http" "os" "runtime" ) // Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one. type Recovery struct { Logger *log.Logger PrintStack bool StackAll bool StackSize int } // NewRecovery returns a new instance of Recovery func NewRecovery() *Recovery { return &Recovery{ Logger: log.New(os.Stdout, "[negroni] ", 0), PrintStack: true, StackAll: false, StackSize: 1024 * 8, } } func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { defer func() { if err := recover(); err != nil { rw.WriteHeader(http.StatusInternalServerError) stack := make([]byte, rec.StackSize) stack = stack[:runtime.Stack(stack, rec.StackAll)] f := "PANIC: %s\n%s" rec.Logger.Printf(f, err, stack) if rec.PrintStack { fmt.Fprintf(rw, f, err, stack) } } }() next(rw, r) }