// ServeHTTP delegates to h.Handler, tracing the transaction with
// h.Tracer, or apm.DefaultTracer if h.Tracer is nil.
func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !h.tracer.Active() || h.requestIgnorer(req) {
h.handler.ServeHTTP(w, req)
return
}
tx, req := StartTransaction(h.tracer, h.requestName(req), req)
defer tx.End()
body := h.tracer.CaptureHTTPRequestBody(req)
w, resp := WrapResponseWriter(w)
defer func() {
if v := recover(); v != nil {
if resp.StatusCode == 0 {
w.WriteHeader(http.StatusInternalServerError)
}
h.recovery(w, req, resp, body, tx, v)
}
SetTransactionContext(tx, req, resp, body)
body.Discard()
}()
h.handler.ServeHTTP(w, req)
if resp.StatusCode == 0 {
resp.StatusCode = http.StatusOK
}
}
For me seems not really good idea for recovery here - breaking of single responsibility principle.
I think it should throw panic to a higher level after logging.
// ServeHTTP delegates to h.Handler, tracing the transaction with
// h.Tracer, or apm.DefaultTracer if h.Tracer is nil.
func (h *handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !h.tracer.Active() || h.requestIgnorer(req) {
h.handler.ServeHTTP(w, req)
return
}
tx, req := StartTransaction(h.tracer, h.requestName(req), req)
defer tx.End()
body := h.tracer.CaptureHTTPRequestBody(req)
w, resp := WrapResponseWriter(w)
defer func() {
v := recover()
if v != nil {
if resp.StatusCode == 0 {
w.WriteHeader(http.StatusInternalServerError)
}
}
SetTransactionContext(tx, req, resp, body)
body.Discard()
panic(v)
}()
h.handler.ServeHTTP(w, req)
if resp.StatusCode == 0 {
resp.StatusCode = http.StatusOK
}
}