Foreword: Hey there, I really like this package (and I really like not needing to maintain my own).
Because you're running the http handler in a new goroutine, if the handler panics it will take down the whole program. The standard http server actually recovers from panics in handlers, so crashing completely is pretty bad.
There easiest solution is just to move to locks. Code gets simpler and faster.
Little program to reproduce:
package main
import (
"log"
"net/http"
"net/http/httptest"
"github.com/felixge/httpsnoop"
)
func main() {
badHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
panic("oh no!")
})
server1 := httptest.NewServer(badHandler)
defer server1.Close()
server2 := httptest.NewServer(metricsMiddleware(badHandler))
defer server2.Close()
// This should cause the server to print out a panic traceback, but not to actually die.
http.Get(server1.URL)
log.Println("Program continued executing!!!")
http.Get(server2.URL)
log.Println("Program died so I won't get printed :(")
}
func metricsMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
metrics := httpsnoop.CaptureMetrics(h, w, r)
log.Printf("response code was: %d", metrics.Code)
})
}
Foreword: Hey there, I really like this package (and I really like not needing to maintain my own).
Because you're running the http handler in a new goroutine, if the handler panics it will take down the whole program. The standard http server actually recovers from panics in handlers, so crashing completely is pretty bad.
There easiest solution is just to move to locks. Code gets simpler and faster.
Little program to reproduce: