julienschmidt / httprouter

A high performance HTTP request router that scales well
https://pkg.go.dev/github.com/julienschmidt/httprouter
BSD 3-Clause "New" or "Revised" License
16.64k stars 1.47k forks source link

Catching Exception for the PanicHandler #217

Open jeffreyyong opened 7 years ago

jeffreyyong commented 7 years ago

Hi,

I'm wondering what is the best way to implement catching the error returned by the PanicHandler. Especially if I want to log the error to something like Sentry. What is the best way of catching panics? Thanks

manawasp commented 7 years ago

Hello,

I'm interresting by the answer too. Currently I'm not using the PanicHandler from Router but a custom handler at the top.

func Panic(next httprouter.Handle) httprouter.Handle {
    return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
        var err error
        defer func() {
            r := recover()
            if r != nil {
                switch t := r.(type) {
                case string:
                    err = errors.New(t)
                case error:
                    err = t
                default:
                    err = errors.New("Unknown error")
                }
                w.WriteHeader(http.StatusInternalServerError)
                w.Write([]byte(fmt.Sprintf("500 - %s", err)))
            }
        }()
        next(w, r, ps)
    }
}
alexaandru commented 7 years ago

Hi,

Not sure why you needed that, this worked for me just fine:

func dieHard(w http.ResponseWriter, r *http.Request, err interface{}) {
    log.Println(r.URL.Path, err)
    w.WriteHeader(http.StatusInternalServerError)
}

router.PanicHandler = dieHard
abhi-illuminasy commented 5 years ago

hi, Thanks, but how do i log the panic from dieHad method? I meant with stack trace?

sharmendran commented 4 years ago

We can collect the panic stack trace using runtime/debug. Like,

 func dieHard(w http.ResponseWriter, r *http.Request, err interface{}) {
   log.Println(r.URL.Path, string(debug.Stack())) // Collecting panic trace
   debug.PrintStack() // or we can use PrintStack
   w.WriteHeader(http.StatusInternalServerError)
}
azlan commented 2 years ago

Stack trace alternative

buf := make([]byte, 4*1024)
runtime.Stack(buf, true)
fmt.Printf("%s", buf)