From 33a94c0ca29593c10e9e4998042dd0ed6c1e1746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=BClhamit=20Yilmaz?= Date: Sat, 4 Apr 2015 15:13:40 +0200 Subject: [PATCH 1/3] Add TestNoRecovery --- recovery_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/recovery_test.go b/recovery_test.go index 3fa264a..63d7a3e 100644 --- a/recovery_test.go +++ b/recovery_test.go @@ -8,6 +8,25 @@ import ( "testing" ) +func TestNoRecovery(t *testing.T) { + buff := bytes.NewBufferString("") + recorder := httptest.NewRecorder() + + rec := NewRecovery() + rec.Logger = log.New(buff, "[negroni] ", 0) + + n := New() + // replace log for testing + n.Use(rec) + n.UseHandler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + fmt.Fprint(res, "writing") + })) + n.ServeHTTP(recorder, (*http.Request)(nil)) + expect(t, recorder.Code, http.StatusOK) + refute(t, recorder.Body.Len(), 0) + expect(t, len(buff.String()), 0) +} + func TestRecovery(t *testing.T) { buff := bytes.NewBufferString("") recorder := httptest.NewRecorder() From ad161faadd56b6ada76d36e726f39160d88da9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=BClhamit=20Yilmaz?= Date: Sat, 4 Apr 2015 15:23:11 +0200 Subject: [PATCH 2/3] Add TestRecoveryAfterWriting --- recovery_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/recovery_test.go b/recovery_test.go index 63d7a3e..d213af7 100644 --- a/recovery_test.go +++ b/recovery_test.go @@ -45,3 +45,23 @@ func TestRecovery(t *testing.T) { refute(t, recorder.Body.Len(), 0) refute(t, len(buff.String()), 0) } + +func TestRecoveryAfterWriting(t *testing.T) { + buff := bytes.NewBufferString("") + recorder := httptest.NewRecorder() + + rec := NewRecovery() + rec.Logger = log.New(buff, "[negroni] ", 0) + + n := New() + // replace log for testing + n.Use(rec) + n.UseHandler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { + fmt.Fprint(res, "writing") + panic("here is a panic!") + })) + n.ServeHTTP(recorder, (*http.Request)(nil)) + expect(t, recorder.Code, http.StatusInternalServerError) + refute(t, recorder.Body.Len(), 0) + refute(t, len(buff.String()), 0) +} From d3a293821e903733ef5c286c6e29346478db7b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abd=C3=BClhamit=20Yilmaz?= Date: Sat, 4 Apr 2015 15:26:01 +0200 Subject: [PATCH 3/3] Fix for passing TestRecoveryAfterWriting --- recovery.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/recovery.go b/recovery.go index d790cad..95784f7 100644 --- a/recovery.go +++ b/recovery.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "net/http" + "net/http/httptest" "os" "runtime" ) @@ -27,6 +28,9 @@ func NewRecovery() *Recovery { } func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { + nr := httptest.NewRecorder() + nrw := NewResponseWriter(nr) + defer func() { if err := recover(); err != nil { rw.WriteHeader(http.StatusInternalServerError) @@ -39,8 +43,14 @@ func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next htt if rec.PrintStack { fmt.Fprintf(rw, f, err, stack) } + } else { + for k, v := range nrw.Header() { + rw.Header()[k] = v + } + rw.WriteHeader(nr.Code) + rw.Write(nr.Body.Bytes()) } }() - next(rw, r) + next(nrw, r) }