package middleware
|
|
|
|
import (
|
|
"bytes"
|
|
"log"
|
|
"net/http"
|
|
"runtime/debug"
|
|
|
|
"github.com/zenazn/goji/web"
|
|
)
|
|
|
|
// Recoverer is a middleware that recovers from panics, logs the panic (and a
|
|
// backtrace), and returns a HTTP 500 (Internal Server Error) status if
|
|
// possible.
|
|
//
|
|
// Recoverer prints a request ID if one is provided.
|
|
func Recoverer(c *web.C, h http.Handler) http.Handler {
|
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
|
reqID := GetReqID(*c)
|
|
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
printPanic(reqID, err)
|
|
debug.PrintStack()
|
|
http.Error(w, http.StatusText(500), 500)
|
|
}
|
|
}()
|
|
|
|
h.ServeHTTP(w, r)
|
|
}
|
|
|
|
return http.HandlerFunc(fn)
|
|
}
|
|
|
|
func printPanic(reqID string, err interface{}) {
|
|
var buf bytes.Buffer
|
|
|
|
if reqID != "" {
|
|
cW(&buf, bBlack, "[%s] ", reqID)
|
|
}
|
|
cW(&buf, bRed, "panic: %+v", err)
|
|
|
|
log.Print(buf.String())
|
|
}
|