aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/urfave/negroni/recovery.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/urfave/negroni/recovery.go')
-rw-r--r--vendor/github.com/urfave/negroni/recovery.go65
1 files changed, 65 insertions, 0 deletions
diff --git a/vendor/github.com/urfave/negroni/recovery.go b/vendor/github.com/urfave/negroni/recovery.go
new file mode 100644
index 0000000..8396cb1
--- /dev/null
+++ b/vendor/github.com/urfave/negroni/recovery.go
@@ -0,0 +1,65 @@
+package negroni
+
+import (
+ "fmt"
+ "log"
+ "net/http"
+ "os"
+ "runtime"
+ "runtime/debug"
+)
+
+// Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one.
+type Recovery struct {
+ Logger ALogger
+ PrintStack bool
+ ErrorHandlerFunc func(interface{})
+ 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 {
+ if rw.Header().Get("Content-Type") == "" {
+ rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ }
+
+ 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)
+ }
+
+ if rec.ErrorHandlerFunc != nil {
+ func() {
+ defer func() {
+ if err := recover(); err != nil {
+ rec.Logger.Printf("provided ErrorHandlerFunc panic'd: %s, trace:\n%s", err, debug.Stack())
+ rec.Logger.Printf("%s\n", debug.Stack())
+ }
+ }()
+ rec.ErrorHandlerFunc(err)
+ }()
+ }
+ }
+ }()
+
+ next(rw, r)
+}