Merge pull request #741 from jaffee/707-catch-panics

add recovery in top level handler
This commit is contained in:
Matthew Jaffee 2017-07-24 14:56:37 -07:00 • committed by GitHub
commit 24800739f2
2 changed files with 35 additions and 0 deletions

View file

@ -29,6 +29,7 @@ import (
"net/http"
_ "net/http/pprof"
"os"
"runtime/debug"
"strconv"
"strings"
"time"
@ -138,6 +139,16 @@ func (h *Handler) methodNotAllowedHandler(w http.ResponseWriter, r *http.Request
// ServeHTTP handles an HTTP request.
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
w.WriteHeader(http.StatusInternalServerError)
stack := debug.Stack()
msg := "PANIC: %s\n%s"
fmt.Fprintf(h.LogOutput, msg, err, stack)
fmt.Fprintf(w, msg, err, stack)
}
}()
t := time.Now()
h.Router.ServeHTTP(w, r)
dif := time.Since(t)

View file

@ -32,6 +32,30 @@ import (
"github.com/pilosa/pilosa/test"
)
func TestHandlerPanics(t *testing.T) {
h := test.NewHandler()
buf := &bytes.Buffer{}
h.Handler.LogOutput = buf
w := httptest.NewRecorder()
// will panic since Handler has no Holder set up
h.ServeHTTP(w, test.MustNewHTTPRequest("GET", "/index/taxi", nil))
bufbytes, err := ioutil.ReadAll(buf)
if err != nil {
t.Fatalf("reading all logoutput: %v", err)
}
if !bytes.Contains(bufbytes, []byte("PANIC: runtime error: invalid memory address or nil pointer dereference")) {
t.Fatalf("expected panic in log, but got: %s", bufbytes)
}
if w.Code != http.StatusInternalServerError {
t.Fatalf("expected internal server error, but got: %v", w.Code)
}
bodyBytes := w.Body.Bytes()
if !bytes.Contains(bodyBytes, []byte("PANIC: runtime error: invalid memory address or nil pointer dereference")) {
t.Fatalf("response to client should have panic, but got %s", bodyBytes)
}
}
// Ensure the handler returns "not found" for invalid paths.
func TestHandler_NotFound(t *testing.T) {
hldr := test.MustOpenHolder()