diff --git a/server/channels/api4/post_test.go b/server/channels/api4/post_test.go index d926ee9541..736642e374 100644 --- a/server/channels/api4/post_test.go +++ b/server/channels/api4/post_test.go @@ -1497,6 +1497,15 @@ func TestPatchPost(t *testing.T) { }) t.Run("invalid requests", func(t *testing.T) { + var origEnableDeveloper bool + th.App.UpdateConfig(func(cfg *model.Config) { + origEnableDeveloper = *cfg.ServiceSettings.EnableDeveloper + *cfg.ServiceSettings.EnableDeveloper = true + }) + defer th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.EnableDeveloper = origEnableDeveloper + }) + r, err := client.DoAPIPut(context.Background(), "/posts/"+post.Id+"/patch", "garbage") require.EqualError(t, err, "Invalid or missing post in request body., invalid character 'g' looking for beginning of value") require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code") diff --git a/server/channels/app/platform/websocket_router.go b/server/channels/app/platform/websocket_router.go index 2a5482d530..9e4fc626f9 100644 --- a/server/channels/app/platform/websocket_router.go +++ b/server/channels/app/platform/websocket_router.go @@ -134,7 +134,7 @@ func returnWebSocketError(ps *PlatformService, conn *WebConn, r *model.WebSocket return } - err.DetailedError = "" + err.WipeDetailed() errorResp := model.NewWebSocketError(r.Seq, err) hub.SendMessage(conn, errorResp) } diff --git a/server/channels/web/handlers.go b/server/channels/web/handlers.go index ec4dadefe7..9532eb6f12 100644 --- a/server/channels/web/handlers.go +++ b/server/channels/web/handlers.go @@ -394,14 +394,14 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Block out detailed error when not in developer mode if !*c.App.Config().ServiceSettings.EnableDeveloper { - c.Err.DetailedError = "" + c.Err.WipeDetailed() } // Sanitize all 5xx error messages in hardened mode if *c.App.Config().ServiceSettings.ExperimentalEnableHardenedMode && c.Err.StatusCode >= 500 { c.Err.Id = "" c.Err.Message = "Internal Server Error" - c.Err.DetailedError = "" + c.Err.WipeDetailed() c.Err.StatusCode = 500 c.Err.Where = "" c.Err.IsOAuth = false diff --git a/server/channels/wsapi/websocket_handler.go b/server/channels/wsapi/websocket_handler.go index 0898a6386f..bbd6f74052 100644 --- a/server/channels/wsapi/websocket_handler.go +++ b/server/channels/wsapi/websocket_handler.go @@ -41,7 +41,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo mlog.String("error_message", sessionErr.SystemMessage(i18n.T)), mlog.Err(sessionErr), ) - sessionErr.DetailedError = "" + sessionErr.WipeDetailed() errResp := model.NewWebSocketError(r.Seq, sessionErr) hub.SendMessage(conn, errResp) return @@ -63,7 +63,7 @@ func (wh webSocketHandler) ServeWebSocket(conn *platform.WebConn, r *model.WebSo mlog.String("error_message", err.SystemMessage(i18n.T)), mlog.Err(err), ) - err.DetailedError = "" + err.WipeDetailed() errResp := model.NewWebSocketError(r.Seq, err) hub.SendMessage(conn, errResp) return diff --git a/server/public/model/utils.go b/server/public/model/utils.go index 8256ea8ebe..3533634b26 100644 --- a/server/public/model/utils.go +++ b/server/public/model/utils.go @@ -336,6 +336,11 @@ func (er *AppError) Wrap(err error) *AppError { return er } +func (er *AppError) WipeDetailed() { + er.wrapped = nil + er.DetailedError = "" +} + // AppErrorFromJSON will try to decode the input into an AppError. func AppErrorFromJSON(r io.Reader) error { data, err := io.ReadAll(r) diff --git a/server/public/model/utils_test.go b/server/public/model/utils_test.go index d091e0575e..c468d06ed8 100644 --- a/server/public/model/utils_test.go +++ b/server/public/model/utils_test.go @@ -150,6 +150,20 @@ func TestAppErrorSerialize(t *testing.T) { require.EqualError(t, berr, aerr.Error()) }) + t.Run("Wipe Detailed", func(t *testing.T) { + aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot) + aerr.WipeDetailed() + js := aerr.ToJSON() + err := AppErrorFromJSON(strings.NewReader(js)) + berr, ok := err.(*AppError) + require.True(t, ok) + require.Equal(t, "message", berr.Id) + require.Equal(t, "", berr.DetailedError) + require.Equal(t, http.StatusTeapot, berr.StatusCode) + + require.EqualError(t, berr, aerr.Error()) + }) + t.Run("Wrapped", func(t *testing.T) { aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped")) js := aerr.ToJSON() @@ -163,6 +177,20 @@ func TestAppErrorSerialize(t *testing.T) { require.EqualError(t, berr, aerr.Error()) }) + t.Run("Wipe Wrapped", func(t *testing.T) { + aerr := NewAppError("", "message", nil, "", http.StatusTeapot).Wrap(errors.New("wrapped")) + aerr.WipeDetailed() + js := aerr.ToJSON() + err := AppErrorFromJSON(strings.NewReader(js)) + berr, ok := err.(*AppError) + require.True(t, ok) + require.Equal(t, "message", berr.Id) + require.Equal(t, "", berr.DetailedError) + require.Equal(t, http.StatusTeapot, berr.StatusCode) + + require.EqualError(t, berr, aerr.Error()) + }) + t.Run("Detailed + Wrapped", func(t *testing.T) { aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped")) js := aerr.ToJSON() @@ -176,6 +204,20 @@ func TestAppErrorSerialize(t *testing.T) { require.EqualError(t, berr, aerr.Error()) }) + t.Run("Detailed + Wrapped", func(t *testing.T) { + aerr := NewAppError("", "message", nil, "detail", http.StatusTeapot).Wrap(errors.New("wrapped")) + aerr.WipeDetailed() + js := aerr.ToJSON() + err := AppErrorFromJSON(strings.NewReader(js)) + berr, ok := err.(*AppError) + require.True(t, ok) + require.Equal(t, "message", berr.Id) + require.Equal(t, "", berr.DetailedError) + require.Equal(t, http.StatusTeapot, berr.StatusCode) + + require.EqualError(t, berr, aerr.Error()) + }) + t.Run("Where", func(t *testing.T) { appErr := NewAppError("TestAppError", "message", nil, "", http.StatusInternalServerError) json := appErr.ToJSON()