From 4d42df5ffc412c19959e6edadd273d1d96984eee Mon Sep 17 00:00:00 2001 From: Fabio Bozzo Date: Fri, 5 Apr 2024 15:16:57 +0200 Subject: [PATCH] fix(http): return error in case of panic --- http/errors_test.go | 12 ++++++++++++ http/handler.go | 12 +++++++++++- http/handler_test.go | 13 +++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/http/errors_test.go b/http/errors_test.go index c08380a9..2329d430 100644 --- a/http/errors_test.go +++ b/http/errors_test.go @@ -112,6 +112,18 @@ func TestErrors(t *testing.T) { status: "200 OK", bodyStr: "the reader call returns a reader.", }, + + { + path: []string{"panic"}, + status: "500 Internal Server Error", + bodyStr: `{"Message":"an error occurred","Code":0,"Type":"error"}` + "\n", + }, + { + path: []string{"latepanic"}, + status: "200 OK", + bodyStr: `"some value"` + "\n", + errTrailer: "an error occurred", + }, } mkTest := func(tc testcase) func(*testing.T) { diff --git a/http/handler.go b/http/handler.go index 9afd4a4d..8b844310 100644 --- a/http/handler.go +++ b/http/handler.go @@ -89,11 +89,21 @@ type requestLogger interface { func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Debug("incoming API request: ", r.URL) + var re ResponseEmitter + defer func() { if r := recover(); r != nil { log.Error("a panic has occurred in the commands handler!") log.Error(r) log.Errorf("stack trace:\n%s", debug.Stack()) + + if re != nil { + if err := re.CloseWithError(errors.New("an error occurred")); err != nil { + log.Errorf("error closing ResponseEmitter: %s", err) + + return + } + } } }() @@ -178,7 +188,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } defer cancel() - re, err := NewResponseEmitter(w, r.Method, req, withRequestBodyEOFChan(bodyEOFChan)) + re, err = NewResponseEmitter(w, r.Method, req, withRequestBodyEOFChan(bodyEOFChan)) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return diff --git a/http/handler_test.go b/http/handler_test.go index f46b7268..9dab5e7a 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -287,6 +287,19 @@ var ( }), }, }, + + "panic": { + Run: func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error { + panic("Invalid memory address or nil pointer dereference") + }, + }, + "latepanic": { + Run: func(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment) error { + re.Emit("some value") + panic("Invalid memory address or nil pointer dereference") + }, + Type: "", + }, }, } )