From a886a67b2caa35c3eeab99a506ddcb9228bbd079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georg=20M=C3=BCller?= Date: Fri, 5 Nov 2021 10:44:14 +0100 Subject: [PATCH 1/2] add testcase with bad json content in NewHttpError The /bad-json-err testcase fails with current code, it returns 200 Ok instead. --- echo_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/echo_test.go b/echo_test.go index f28915864..d448bdd9b 100644 --- a/echo_test.go +++ b/echo_test.go @@ -1132,6 +1132,14 @@ func TestDefaultHTTPErrorHandler(t *testing.T) { err := errors.New("internal error message body") return NewHTTPError(http.StatusBadRequest).SetInternal(err) }) + e.GET("/bad-json", func(c Context) error { + err := errors.New("test error") + return c.JSON(http.StatusOK, err.Error) // <- missing () after 'Error' + }) + e.GET("/bad-json-err", func(c Context) error { + err := errors.New("test error") + return NewHTTPError(http.StatusBadRequest, err.Error) // <- missing () after 'Error' + }) // With Debug=true plain response contains error message c, b := request(http.MethodGet, "/plain", e) @@ -1153,6 +1161,12 @@ func TestDefaultHTTPErrorHandler(t *testing.T) { c, b = request(http.MethodGet, "/internal-error", e) assert.Equal(t, http.StatusBadRequest, c) assert.Equal(t, "{\n \"error\": \"code=400, message=Bad Request, internal=internal error message body\",\n \"message\": \"Bad Request\"\n}\n", b) + c, b = request(http.MethodGet, "/bad-json", e) + assert.Equal(t, http.StatusInternalServerError, c) + assert.Equal(t, "{\n \"error\": \"json: unsupported type: func() string\",\n \"message\": \"Internal Server Error\"\n}\n", b) + c, b = request(http.MethodGet, "/bad-json-err", e) + assert.Equal(t, http.StatusInternalServerError, c) + assert.Equal(t, "{\n \"error\": \"json: unsupported type: func() string\",\n \"message\": \"Internal Server Error\"\n}\n", b) e.Debug = false // With Debug=false the error response is shortened From 3b4096e9d92146d4c0a528cada85c2fd7bfe810a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georg=20M=C3=BCller?= Date: Fri, 5 Nov 2021 10:45:03 +0100 Subject: [PATCH 2/2] return InternalServerError in DefaultHTTPErrorHandler if c.JSON() fails This returns the same response as when calling c.JSON() directly --- echo.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/echo.go b/echo.go index df5d35843..9b35b964d 100644 --- a/echo.go +++ b/echo.go @@ -401,6 +401,22 @@ func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) { } if err != nil { e.Logger.Error(err) + + if e.Debug { + message = Map{"message": http.StatusText(http.StatusInternalServerError), "error": err.Error()} + } else { + message = Map{"message": http.StatusText(http.StatusInternalServerError)} + } + + if c.Request().Method == http.MethodHead { + err = c.NoContent(http.StatusInternalServerError) + } else { + err = c.JSON(http.StatusInternalServerError, message) + } + if err != nil { + e.Logger.Error("Sending internal message failed as well:", err) + // TODO maybe cancel whole connection here? + } } }