From 832736da376af734ee7b63d3a7cb0f23a266e305 Mon Sep 17 00:00:00 2001 From: Tim Scheuermann Date: Thu, 28 Jul 2022 18:05:03 +0300 Subject: [PATCH] [MM-45990] log JSON parsing errors in API4 (#20724) --- api4/bot.go | 16 +++++------ api4/channel.go | 22 +++++++-------- api4/channel_category.go | 6 ++-- api4/channel_local.go | 4 +-- api4/cloud.go | 2 +- api4/command.go | 20 ++++++------- api4/command_local.go | 4 +-- api4/command_test.go | 14 ++++----- api4/compliance.go | 8 +++--- api4/config.go | 6 ++-- api4/config_local.go | 6 ++-- api4/data_retention.go | 16 +++++------ api4/emoji.go | 14 ++++----- api4/file.go | 8 +++--- api4/file_test.go | 2 +- api4/graphql.go | 2 +- api4/graphql_client.go | 2 +- api4/group.go | 8 +++--- api4/integration_action.go | 10 +++++-- api4/job.go | 6 ++-- api4/ldap.go | 6 +++- api4/license.go | 2 +- api4/license_local.go | 2 +- api4/oauth.go | 14 ++++----- api4/plugin.go | 10 +++---- api4/post.go | 23 +++++++++------ api4/post_test.go | 8 ++++-- api4/preference.go | 10 +++---- api4/reaction.go | 4 +-- api4/remote_cluster.go | 8 +++--- api4/role.go | 8 +++--- api4/saml.go | 18 ++++++++---- api4/scheme.go | 12 ++++---- api4/status.go | 8 +++--- api4/system.go | 14 ++++----- api4/team.go | 44 ++++++++++++++--------------- api4/team_local.go | 4 +-- api4/terms_of_service.go | 6 ++-- api4/upload.go | 8 +++--- api4/user.go | 18 ++++++------ api4/user_local.go | 6 ++-- api4/webhook.go | 22 +++++++-------- api4/webhook_local.go | 8 +++--- app/plugin_api_test.go | 4 +-- app/plugin_test.go | 2 +- model/utils.go | 53 +++++++++++++++++++++++++++-------- model/utils_test.go | 27 ++++++++++++++++++ shared/mail/inbucket.go | 7 ++--- store/storetest/team_store.go | 4 +-- testlib/assertions.go | 2 ++ web/context.go | 6 ++++ 51 files changed, 316 insertions(+), 228 deletions(-) diff --git a/api4/bot.go b/api4/bot.go index 15acae8cf6..569d51b793 100644 --- a/api4/bot.go +++ b/api4/bot.go @@ -28,7 +28,7 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { var botPatch *model.BotPatch err := json.NewDecoder(r.Body).Decode(&botPatch) if err != nil { - c.SetInvalidParam("bot") + c.SetInvalidParamWithErr("bot", err) return } @@ -70,7 +70,7 @@ func createBot(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(createdBot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -84,7 +84,7 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { var botPatch *model.BotPatch err := json.NewDecoder(r.Body).Decode(&botPatch) if err != nil { - c.SetInvalidParam("bot") + c.SetInvalidParamWithErr("bot", err) return } @@ -109,7 +109,7 @@ func patchBot(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(updatedBot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -150,7 +150,7 @@ func getBot(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(bot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -268,7 +268,7 @@ func assignBot(c *Context, w http.ResponseWriter, _ *http.Request) { auditRec.AddEventObjectType("bot") if err := json.NewEncoder(w).Encode(bot); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -287,7 +287,7 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { var userPatch model.UserPatch jsonErr := json.NewDecoder(r.Body).Decode(&userPatch) if jsonErr != nil || userPatch.Password == nil || *userPatch.Password == "" { - c.SetInvalidParam("userPatch") + c.SetInvalidParamWithErr("userPatch", jsonErr) return } @@ -315,6 +315,6 @@ func convertBotToUser(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventObjectType("user") if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/channel.go b/api4/channel.go index c686bfd272..954ec5632e 100644 --- a/api4/channel.go +++ b/api4/channel.go @@ -82,7 +82,7 @@ func createChannel(c *Context, w http.ResponseWriter, r *http.Request) { var channel *model.Channel err := json.NewDecoder(r.Body).Decode(&channel) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -126,7 +126,7 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) { var channel *model.Channel err := json.NewDecoder(r.Body).Decode(&channel) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -303,7 +303,7 @@ func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) { var patch *model.ChannelPatch err := json.NewDecoder(r.Body).Decode(&patch) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -482,7 +482,7 @@ func searchGroupChannels(c *Context, w http.ResponseWriter, r *http.Request) { var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1057,7 +1057,7 @@ func searchChannelsForTeam(c *Context, w http.ResponseWriter, r *http.Request) { var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1096,7 +1096,7 @@ func searchArchivedChannelsForTeam(c *Context, w http.ResponseWriter, r *http.Re var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1130,7 +1130,7 @@ func searchAllChannels(c *Context, w http.ResponseWriter, r *http.Request) { var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -1470,7 +1470,7 @@ func viewChannel(c *Context, w http.ResponseWriter, r *http.Request) { var view model.ChannelView if jsonErr := json.NewDecoder(r.Body).Decode(&view); jsonErr != nil { - c.SetInvalidParam("channel_view") + c.SetInvalidParamWithErr("channel_view", jsonErr) return } @@ -1547,7 +1547,7 @@ func updateChannelMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.R var schemeRoles model.SchemeRoles if jsonErr := json.NewDecoder(r.Body).Decode(&schemeRoles); jsonErr != nil { - c.SetInvalidParam("scheme_roles") + c.SetInvalidParamWithErr("scheme_roles", jsonErr) return } @@ -1810,7 +1810,7 @@ func updateChannelScheme(c *Context, w http.ResponseWriter, r *http.Request) { var p model.SchemeIDPatch if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil || p.SchemeID == nil || !model.IsValidId(*p.SchemeID) { - c.SetInvalidParam("scheme_id") + c.SetInvalidParamWithErr("scheme_id", jsonErr) return } schemeID := p.SchemeID @@ -2013,7 +2013,7 @@ func patchChannelModerations(c *Context, w http.ResponseWriter, r *http.Request) var channelModerationsPatch []*model.ChannelModerationPatch err := json.NewDecoder(r.Body).Decode(&channelModerationsPatch) if err != nil { - c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError) + c.Err = model.NewAppError("Api4.patchChannelModerations", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err) return } diff --git a/api4/channel_category.go b/api4/channel_category.go index fe9c0c0ef3..c92b3ff27b 100644 --- a/api4/channel_category.go +++ b/api4/channel_category.go @@ -55,7 +55,7 @@ func createCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req var categoryCreateRequest model.SidebarCategoryWithChannels err := json.NewDecoder(r.Body).Decode(&categoryCreateRequest) if err != nil || c.Params.UserId != categoryCreateRequest.UserId || c.Params.TeamId != categoryCreateRequest.TeamId { - c.SetInvalidParam("category") + c.SetInvalidParamWithErr("category", err) return } @@ -177,7 +177,7 @@ func updateCategoriesForTeamForUser(c *Context, w http.ResponseWriter, r *http.R var categoriesUpdateRequest []*model.SidebarCategoryWithChannels err := json.NewDecoder(r.Body).Decode(&categoriesUpdateRequest) if err != nil { - c.SetInvalidParam("category") + c.SetInvalidParamWithErr("category", err) return } @@ -278,7 +278,7 @@ func updateCategoryForTeamForUser(c *Context, w http.ResponseWriter, r *http.Req var categoryUpdateRequest model.SidebarCategoryWithChannels err := json.NewDecoder(r.Body).Decode(&categoryUpdateRequest) if err != nil || categoryUpdateRequest.TeamId != c.Params.TeamId || categoryUpdateRequest.UserId != c.Params.UserId { - c.SetInvalidParam("category") + c.SetInvalidParamWithErr("category", err) return } diff --git a/api4/channel_local.go b/api4/channel_local.go index bb5286b44f..0c5da46a6c 100644 --- a/api4/channel_local.go +++ b/api4/channel_local.go @@ -41,7 +41,7 @@ func localCreateChannel(c *Context, w http.ResponseWriter, r *http.Request) { var channel *model.Channel err := json.NewDecoder(r.Body).Decode(&channel) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } @@ -284,7 +284,7 @@ func localPatchChannel(c *Context, w http.ResponseWriter, r *http.Request) { var patch *model.ChannelPatch err := json.NewDecoder(r.Body).Decode(&patch) if err != nil { - c.SetInvalidParam("channel") + c.SetInvalidParamWithErr("channel", err) return } diff --git a/api4/cloud.go b/api4/cloud.go index 7ba3fb90f6..825db6d5bb 100644 --- a/api4/cloud.go +++ b/api4/cloud.go @@ -58,7 +58,7 @@ func handleNotifyAdminToUpgrade(c *Context, w http.ResponseWriter, r *http.Reque var notifyAdminRequest *model.NotifyAdminToUpgradeRequest err := json.NewDecoder(r.Body).Decode(¬ifyAdminRequest) if err != nil { - c.SetInvalidParam("notifyAdminRequest") + c.SetInvalidParamWithErr("notifyAdminRequest", err) return } diff --git a/api4/command.go b/api4/command.go index fa627b32d2..c267c869fc 100644 --- a/api4/command.go +++ b/api4/command.go @@ -32,7 +32,7 @@ func (api *API) InitCommand() { func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmd model.Command if jsonErr := json.NewDecoder(r.Body).Decode(&cmd); jsonErr != nil { - c.SetInvalidParam("command") + c.SetInvalidParamWithErr("command", jsonErr) return } @@ -62,7 +62,7 @@ func createCommand(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rcmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -74,7 +74,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmd model.Command if jsonErr := json.NewDecoder(r.Body).Decode(&cmd); jsonErr != nil || cmd.Id != c.Params.CommandId { - c.SetInvalidParam("command") + c.SetInvalidParamWithErr("command", jsonErr) return } @@ -122,7 +122,7 @@ func updateCommand(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(rcmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -134,7 +134,7 @@ func moveCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmr model.CommandMoveRequest if jsonErr := json.NewDecoder(r.Body).Decode(&cmr); jsonErr != nil { - c.SetInvalidParam("team_id") + c.SetInvalidParamWithErr("team_id", jsonErr) return } @@ -274,7 +274,7 @@ func listCommands(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(commands); err != nil { - mlog.Warn("Error writing response", mlog.Err(err)) + c.Logger.Warn("Error writing response", mlog.Err(err)) } } @@ -305,14 +305,14 @@ func getCommand(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(cmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { var commandArgs model.CommandArgs if jsonErr := json.NewDecoder(r.Body).Decode(&commandArgs); jsonErr != nil { - c.SetInvalidParam("command_args") + c.SetInvalidParamWithErr("command_args", jsonErr) return } @@ -368,7 +368,7 @@ func executeCommand(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -390,7 +390,7 @@ func listAutocompleteCommands(c *Context, w http.ResponseWriter, r *http.Request } if err := json.NewEncoder(w).Encode(commands); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/command_local.go b/api4/command_local.go index cf22bb744a..216caa7773 100644 --- a/api4/command_local.go +++ b/api4/command_local.go @@ -25,7 +25,7 @@ func (api *API) InitCommandLocal() { func localCreateCommand(c *Context, w http.ResponseWriter, r *http.Request) { var cmd model.Command if jsonErr := json.NewDecoder(r.Body).Decode(&cmd); jsonErr != nil { - c.SetInvalidParam("command") + c.SetInvalidParamWithErr("command", jsonErr) return } @@ -47,6 +47,6 @@ func localCreateCommand(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rcmd); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/command_test.go b/api4/command_test.go index 3f493607ff..2f47a8dca6 100644 --- a/api4/command_test.go +++ b/api4/command_test.go @@ -646,7 +646,7 @@ func TestExecuteInvalidCommand(t *testing.T) { rc := &model.CommandResponse{} if err := json.NewEncoder(w).Encode(rc); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -732,7 +732,7 @@ func TestExecuteGetCommand(t *testing.T) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -792,7 +792,7 @@ func TestExecutePostCommand(t *testing.T) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -846,7 +846,7 @@ func TestExecuteCommandAgainstChannelOnAnotherTeam(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -898,7 +898,7 @@ func TestExecuteCommandAgainstChannelUserIsNotIn(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -958,7 +958,7 @@ func TestExecuteCommandInDirectMessageChannel(t *testing.T) { require.Equal(t, http.MethodPost, r.Method) w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() @@ -1025,7 +1025,7 @@ func TestExecuteCommandInTeamUserIsNotOn(t *testing.T) { w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(expectedCommandResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + th.TestLogger.Warn("Error while writing response", mlog.Err(err)) } })) defer ts.Close() diff --git a/api4/compliance.go b/api4/compliance.go index f828a03c08..f7987e1b82 100644 --- a/api4/compliance.go +++ b/api4/compliance.go @@ -25,7 +25,7 @@ func (api *API) InitCompliance() { func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) { var job model.Compliance if jsonErr := json.NewDecoder(r.Body).Decode(&job); jsonErr != nil { - c.SetInvalidParam("compliance") + c.SetInvalidParamWithErr("compliance", jsonErr) return } @@ -55,7 +55,7 @@ func createComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rjob); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -76,7 +76,7 @@ func getComplianceReports(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(crs); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -106,7 +106,7 @@ func getComplianceReport(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddMeta("compliance_desc", job.Desc) if err := json.NewEncoder(w).Encode(job); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/config.go b/api4/config.go index e08cdccf55..c20e3e2912 100644 --- a/api4/config.go +++ b/api4/config.go @@ -78,7 +78,7 @@ func getConfig(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -220,7 +220,7 @@ func updateConfig(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -370,7 +370,7 @@ func patchConfig(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/config_local.go b/api4/config_local.go index b120e93bd7..baf019ecc9 100644 --- a/api4/config_local.go +++ b/api4/config_local.go @@ -30,7 +30,7 @@ func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(cfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -82,7 +82,7 @@ func localUpdateConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(newCfg); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -137,7 +137,7 @@ func localPatchConfig(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(c.App.GetSanitizedConfig()); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/data_retention.go b/api4/data_retention.go index 0749c1d5a5..0059e8ea89 100644 --- a/api4/data_retention.go +++ b/api4/data_retention.go @@ -111,7 +111,7 @@ func getPolicy(c *Context, w http.ResponseWriter, r *http.Request) { func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var policy model.RetentionPolicyWithTeamAndChannelIDs if jsonErr := json.NewDecoder(r.Body).Decode(&policy); jsonErr != nil { - c.SetInvalidParam("policy") + c.SetInvalidParamWithErr("policy", jsonErr) return } auditRec := c.MakeAuditRecord("createPolicy", audit.Fail) @@ -144,7 +144,7 @@ func createPolicy(c *Context, w http.ResponseWriter, r *http.Request) { func patchPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.RetentionPolicyWithTeamAndChannelIDs if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("policy") + c.SetInvalidParamWithErr("policy", jsonErr) return } c.RequirePolicyId() @@ -233,7 +233,7 @@ func searchTeamsInPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var props model.TeamSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("team_search") + c.SetInvalidParamWithErr("team_search", jsonErr) return } @@ -261,7 +261,7 @@ func addTeamsToPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var teamIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&teamIDs) if jsonErr != nil { - c.SetInvalidParam("team_ids") + c.SetInvalidParamWithErr("team_ids", jsonErr) return } auditRec := c.MakeAuditRecord("addTeamsToPolicy", audit.Fail) @@ -289,7 +289,7 @@ func removeTeamsFromPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var teamIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&teamIDs) if jsonErr != nil { - c.SetInvalidParam("team_ids") + c.SetInvalidParamWithErr("team_ids", jsonErr) return } auditRec := c.MakeAuditRecord("removeTeamsFromPolicy", audit.Fail) @@ -342,7 +342,7 @@ func searchChannelsInPolicy(c *Context, w http.ResponseWriter, r *http.Request) var props *model.ChannelSearch err := json.NewDecoder(r.Body).Decode(&props) if err != nil { - c.SetInvalidParam("channel_search") + c.SetInvalidParamWithErr("channel_search", err) return } @@ -382,7 +382,7 @@ func addChannelsToPolicy(c *Context, w http.ResponseWriter, r *http.Request) { var channelIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&channelIDs) if jsonErr != nil { - c.SetInvalidParam("channel_ids") + c.SetInvalidParamWithErr("channel_ids", jsonErr) return } auditRec := c.MakeAuditRecord("addChannelsToPolicy", audit.Fail) @@ -411,7 +411,7 @@ func removeChannelsFromPolicy(c *Context, w http.ResponseWriter, r *http.Request var channelIDs []string jsonErr := json.NewDecoder(r.Body).Decode(&channelIDs) if jsonErr != nil { - c.SetInvalidParam("channel_ids") + c.SetInvalidParamWithErr("channel_ids", jsonErr) return } auditRec := c.MakeAuditRecord("removeChannelsFromPolicy", audit.Fail) diff --git a/api4/emoji.go b/api4/emoji.go index 95fb682aae..52b1b017ce 100644 --- a/api4/emoji.go +++ b/api4/emoji.go @@ -98,7 +98,7 @@ func createEmoji(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(newEmoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -121,7 +121,7 @@ func getEmojiList(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(listEmoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -211,7 +211,7 @@ func getEmoji(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -228,7 +228,7 @@ func getEmojiByName(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emoji); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -257,7 +257,7 @@ func getEmojiImage(c *Context, w http.ResponseWriter, r *http.Request) { func searchEmojis(c *Context, w http.ResponseWriter, r *http.Request) { var emojiSearch model.EmojiSearch if jsonErr := json.NewDecoder(r.Body).Decode(&emojiSearch); jsonErr != nil { - c.SetInvalidParam("term") + c.SetInvalidParamWithErr("term", jsonErr) return } @@ -273,7 +273,7 @@ func searchEmojis(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emojis); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -292,6 +292,6 @@ func autocompleteEmojis(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(emojis); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/file.go b/api4/file.go index 6dc5ac04b0..1eadda69b8 100644 --- a/api4/file.go +++ b/api4/file.go @@ -150,7 +150,7 @@ func uploadFileStream(c *Context, w http.ResponseWriter, r *http.Request) { // Write the response values to the output upon return w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(fileUploadResponse); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -632,7 +632,7 @@ func getFileInfo(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "max-age=2592000, private") if err := json.NewEncoder(w).Encode(info); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -759,7 +759,7 @@ func searchFiles(c *Context, w http.ResponseWriter, r *http.Request, teamID stri var params model.SearchParameter jsonErr := json.NewDecoder(r.Body).Decode(¶ms) if jsonErr != nil { - c.Err = model.NewAppError("searchFiles", "api.post.search_files.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("searchFiles", "api.post.search_files.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -821,6 +821,6 @@ func searchFiles(c *Context, w http.ResponseWriter, r *http.Request, teamID stri w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") if err := json.NewEncoder(w).Encode(results); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/file_test.go b/api4/file_test.go index 276dfb4cef..dafb76110e 100644 --- a/api4/file_test.go +++ b/api4/file_test.go @@ -84,7 +84,7 @@ func testDoUploadFileRequest(t testing.TB, c *model.Client4, url string, blob [] var res model.FileUploadResponse if jsonErr := json.NewDecoder(resp.Body).Decode(&res); jsonErr != nil { - return nil, nil, model.NewAppError("doUploadFile", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + return nil, nil, model.NewAppError("doUploadFile", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) } return &res, model.BuildResponse(resp), nil } diff --git a/api4/graphql.go b/api4/graphql.go index 4edbc31c27..41208ec1d0 100644 --- a/api4/graphql.go +++ b/api4/graphql.go @@ -78,7 +78,7 @@ func (api *API) graphQL(c *Context, w http.ResponseWriter, r *http.Request) { defer func() { if response != nil { if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } }() diff --git a/api4/graphql_client.go b/api4/graphql_client.go index 9a85e6a2fa..edc893eeee 100644 --- a/api4/graphql_client.go +++ b/api4/graphql_client.go @@ -44,7 +44,7 @@ func (c *graphQLClient) login(loginId string, password string) (*model.User, *mo var user model.User if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - return nil, nil, model.NewAppError("login", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError) + return nil, nil, model.NewAppError("login", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(jsonErr) } return &user, model.BuildResponse(r), nil } diff --git a/api4/group.go b/api4/group.go index cf0046d213..9d13c18325 100644 --- a/api4/group.go +++ b/api4/group.go @@ -132,7 +132,7 @@ func getGroup(c *Context, w http.ResponseWriter, r *http.Request) { func createGroup(c *Context, w http.ResponseWriter, r *http.Request) { var group *model.GroupWithUserIds if jsonErr := json.NewDecoder(r.Body).Decode(&group); jsonErr != nil { - c.SetInvalidParam("group") + c.SetInvalidParamWithErr("group", jsonErr) return } @@ -215,7 +215,7 @@ func patchGroup(c *Context, w http.ResponseWriter, r *http.Request) { var groupPatch model.GroupPatch if jsonErr := json.NewDecoder(r.Body).Decode(&groupPatch); jsonErr != nil { - c.SetInvalidParam("group") + c.SetInvalidParamWithErr("group", jsonErr) return } @@ -1030,7 +1030,7 @@ func addGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { var newMembers *model.GroupModifyMembers if jsonErr := json.NewDecoder(r.Body).Decode(&newMembers); jsonErr != nil { - c.SetInvalidParam("addGroupMembers") + c.SetInvalidParamWithErr("addGroupMembers", jsonErr) return } @@ -1083,7 +1083,7 @@ func deleteGroupMembers(c *Context, w http.ResponseWriter, r *http.Request) { var deleteBody *model.GroupModifyMembers if jsonErr := json.NewDecoder(r.Body).Decode(&deleteBody); jsonErr != nil { - c.SetInvalidParam("deleteGroupMembers") + c.SetInvalidParamWithErr("deleteGroupMembers", jsonErr) return } diff --git a/api4/integration_action.go b/api4/integration_action.go index 474c1c93ff..aa7e5d7319 100644 --- a/api4/integration_action.go +++ b/api4/integration_action.go @@ -8,6 +8,7 @@ import ( "net/http" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) func (api *API) InitAction() { @@ -24,7 +25,10 @@ func doPostAction(c *Context, w http.ResponseWriter, r *http.Request) { } var actionRequest model.DoPostActionRequest - json.NewDecoder(r.Body).Decode(&actionRequest) + err := json.NewDecoder(r.Body).Decode(&actionRequest) + if err != nil { + c.Logger.Warn("Error decoding the action request", mlog.Err(err)) + } var cookie *model.PostActionCookie if actionRequest.Cookie != "" { @@ -68,7 +72,7 @@ func openDialog(c *Context, w http.ResponseWriter, r *http.Request) { var dialog model.OpenDialogRequest err := json.NewDecoder(r.Body).Decode(&dialog) if err != nil { - c.SetInvalidParam("dialog") + c.SetInvalidParamWithErr("dialog", err) return } @@ -90,7 +94,7 @@ func submitDialog(c *Context, w http.ResponseWriter, r *http.Request) { jsonErr := json.NewDecoder(r.Body).Decode(&submit) if jsonErr != nil { - c.SetInvalidParam("dialog") + c.SetInvalidParamWithErr("dialog", jsonErr) return } diff --git a/api4/job.go b/api4/job.go index 6e2ec56f82..b0622ae8e3 100644 --- a/api4/job.go +++ b/api4/job.go @@ -47,7 +47,7 @@ func getJob(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(job); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -106,7 +106,7 @@ func downloadJob(c *Context, w http.ResponseWriter, r *http.Request) { func createJob(c *Context, w http.ResponseWriter, r *http.Request) { var job model.Job if jsonErr := json.NewDecoder(r.Body).Decode(&job); jsonErr != nil { - c.SetInvalidParam("job") + c.SetInvalidParamWithErr("job", jsonErr) return } @@ -137,7 +137,7 @@ func createJob(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rjob); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/ldap.go b/api4/ldap.go index 4ee9c8cc1f..60cd176c65 100644 --- a/api4/ldap.go +++ b/api4/ldap.go @@ -10,6 +10,7 @@ import ( "github.com/mattermost/mattermost-server/v6/audit" "github.com/mattermost/mattermost-server/v6/model" + "github.com/mattermost/mattermost-server/v6/shared/mlog" ) type mixedUnlinkedGroup struct { @@ -51,7 +52,10 @@ func syncLdap(c *Context, w http.ResponseWriter, r *http.Request) { IncludeRemovedMembers bool `json:"include_removed_members"` } var opts LdapSyncOptions - json.NewDecoder(r.Body).Decode(&opts) + err := json.NewDecoder(r.Body).Decode(&opts) + if err != nil { + c.Logger.Warn("Error decoding LDAP sync options", mlog.Err(err)) + } auditRec := c.MakeAuditRecord("syncLdap", audit.Fail) defer c.LogAuditRec(auditRec) diff --git a/api4/license.go b/api4/license.go index f4b0d079f0..4e308a1a45 100644 --- a/api4/license.go +++ b/api4/license.go @@ -136,7 +136,7 @@ func addLicense(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(license); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/license_local.go b/api4/license_local.go index 7dbb4e51f5..9634fe0488 100644 --- a/api4/license_local.go +++ b/api4/license_local.go @@ -73,7 +73,7 @@ func localAddLicense(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(license); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/oauth.go b/api4/oauth.go index 2cb4c6cc26..96a7ae4586 100644 --- a/api4/oauth.go +++ b/api4/oauth.go @@ -27,7 +27,7 @@ func (api *API) InitOAuth() { func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { var oauthApp model.OAuthApp if jsonErr := json.NewDecoder(r.Body).Decode(&oauthApp); jsonErr != nil { - c.SetInvalidParam("oauth_app") + c.SetInvalidParamWithErr("oauth_app", jsonErr) return } @@ -60,7 +60,7 @@ func createOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rapp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -82,7 +82,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { var oauthApp model.OAuthApp if jsonErr := json.NewDecoder(r.Body).Decode(&oauthApp); jsonErr != nil { - c.SetInvalidParam("oauth_app") + c.SetInvalidParamWithErr("oauth_app", jsonErr) return } auditRec.AddEventParameter("oauth_app", oauthApp) @@ -121,7 +121,7 @@ func updateOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(updatedOAuthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -178,7 +178,7 @@ func getOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(oauthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -196,7 +196,7 @@ func getOAuthAppInfo(c *Context, w http.ResponseWriter, r *http.Request) { oauthApp.Sanitize() if err := json.NewEncoder(w).Encode(oauthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -280,7 +280,7 @@ func regenerateOAuthAppSecret(c *Context, w http.ResponseWriter, r *http.Request c.LogAudit("success") if err := json.NewEncoder(w).Encode(oauthApp); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/plugin.go b/api4/plugin.go index 43a744a070..1ab0aae92c 100644 --- a/api4/plugin.go +++ b/api4/plugin.go @@ -167,7 +167,7 @@ func installMarketplacePlugin(c *Context, w http.ResponseWriter, r *http.Request w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(manifest); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -189,7 +189,7 @@ func getPlugins(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -211,7 +211,7 @@ func getPluginStatuses(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(response); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -402,7 +402,7 @@ func installPlugin(c *Context, w http.ResponseWriter, plugin io.ReadSeeker, forc } w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(manifest); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -462,6 +462,6 @@ func getFirstAdminVisitMarketplaceStatus(c *Context, w http.ResponseWriter, r *h auditRec.Success() if err := json.NewEncoder(w).Encode(firstAdminVisitMarketplaceObj); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/post.go b/api4/post.go index dda1619eb5..7ae86bbc28 100644 --- a/api4/post.go +++ b/api4/post.go @@ -43,7 +43,7 @@ func (api *API) InitPost() { func createPost(c *Context, w http.ResponseWriter, r *http.Request) { var post model.Post if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - c.SetInvalidParam("post") + c.SetInvalidParamWithErr("post", jsonErr) return } @@ -106,14 +106,19 @@ func createPost(c *Context, w http.ResponseWriter, r *http.Request) { // Note that rp has already had PreparePostForClient called on it by App.CreatePost if err := rp.EncodeJSON(w); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func createEphemeralPost(c *Context, w http.ResponseWriter, r *http.Request) { ephRequest := model.PostEphemeral{} - json.NewDecoder(r.Body).Decode(&ephRequest) + jsonErr := json.NewDecoder(r.Body).Decode(&ephRequest) + if jsonErr != nil { + c.SetInvalidParamWithErr("body", jsonErr) + return + } + if ephRequest.UserID == "" { c.SetInvalidParam("user_id") return @@ -476,7 +481,7 @@ func getPostsByIds(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set(model.HeaderFirstInaccessiblePostTime, strconv.FormatInt(firstInaccessiblePostTime, 10)) if err := json.NewEncoder(w).Encode(posts); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -656,7 +661,7 @@ func searchPostsInAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { func searchPosts(c *Context, w http.ResponseWriter, r *http.Request, teamId string) { var params model.SearchParameter if jsonErr := json.NewDecoder(r.Body).Decode(¶ms); jsonErr != nil { - c.Err = model.NewAppError("searchPosts", "api.post.search_posts.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("searchPosts", "api.post.search_posts.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -739,7 +744,7 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { var post model.Post if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - c.SetInvalidParam("post") + c.SetInvalidParamWithErr("post", jsonErr) return } @@ -800,7 +805,7 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) { var post model.PostPatch if jsonErr := json.NewDecoder(r.Body).Decode(&post); jsonErr != nil { - c.SetInvalidParam("post") + c.SetInvalidParamWithErr("post", jsonErr) return } @@ -869,7 +874,7 @@ func setPostUnread(c *Context, w http.ResponseWriter, r *http.Request) { return } if err := json.NewEncoder(w).Encode(state); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -890,7 +895,7 @@ func setPostReminder(c *Context, w http.ResponseWriter, r *http.Request) { var reminder model.PostReminder if jsonErr := json.NewDecoder(r.Body).Decode(&reminder); jsonErr != nil { - c.SetInvalidParam("target_time") + c.SetInvalidParamWithErr("target_time", jsonErr) return } diff --git a/api4/post_test.go b/api4/post_test.go index baa113731b..8e68db254d 100644 --- a/api4/post_test.go +++ b/api4/post_test.go @@ -25,6 +25,7 @@ import ( "github.com/mattermost/mattermost-server/v6/app" "github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/plugin/plugintest/mock" + "github.com/mattermost/mattermost-server/v6/shared/mlog" "github.com/mattermost/mattermost-server/v6/store/storetest/mocks" "github.com/mattermost/mattermost-server/v6/utils" "github.com/mattermost/mattermost-server/v6/utils/testutils" @@ -306,7 +307,10 @@ func testCreatePostWithOutgoingHook( if requestContentType == "application/json" { decoder := json.NewDecoder(r.Body) o := &model.OutgoingWebhookPayload{} - decoder.Decode(&o) + err := decoder.Decode(&o) + if err != nil { + th.TestLogger.Warn("Error decoding body", mlog.Err(err)) + } if !reflect.DeepEqual(expectedPayload, o) { t.Logf("JSON payload is %+v, should be %+v", o, expectedPayload) @@ -924,7 +928,7 @@ func TestPatchPost(t *testing.T) { t.Run("invalid requests", func(t *testing.T) { r, err := client.DoAPIPut("/posts/"+post.Id+"/patch", "garbage") - require.EqualError(t, err, ": Invalid or missing post in request body., ") + require.EqualError(t, err, ": Invalid or missing post in request body.") require.Equal(t, http.StatusBadRequest, r.StatusCode, "wrong status code") patch := &model.PostPatch{} diff --git a/api4/preference.go b/api4/preference.go index 09a19f9834..79928f0320 100644 --- a/api4/preference.go +++ b/api4/preference.go @@ -38,7 +38,7 @@ func getPreferences(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(preferences); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -60,7 +60,7 @@ func getPreferencesByCategory(c *Context, w http.ResponseWriter, r *http.Request } if err := json.NewEncoder(w).Encode(preferences); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -82,7 +82,7 @@ func getPreferenceByCategoryAndName(c *Context, w http.ResponseWriter, r *http.R } if err := json.NewEncoder(w).Encode(preferences); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -102,7 +102,7 @@ func updatePreferences(c *Context, w http.ResponseWriter, r *http.Request) { var preferences model.Preferences if jsonErr := json.NewDecoder(r.Body).Decode(&preferences); jsonErr != nil { - c.SetInvalidParam("preferences") + c.SetInvalidParamWithErr("preferences", jsonErr) return } @@ -150,7 +150,7 @@ func deletePreferences(c *Context, w http.ResponseWriter, r *http.Request) { var preferences model.Preferences if jsonErr := json.NewDecoder(r.Body).Decode(&preferences); jsonErr != nil { - c.SetInvalidParam("preferences") + c.SetInvalidParamWithErr("preferences", jsonErr) return } diff --git a/api4/reaction.go b/api4/reaction.go index ac19502d92..da95d63f5b 100644 --- a/api4/reaction.go +++ b/api4/reaction.go @@ -21,7 +21,7 @@ func (api *API) InitReaction() { func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) { var reaction model.Reaction if jsonErr := json.NewDecoder(r.Body).Decode(&reaction); jsonErr != nil { - c.SetInvalidParam("reaction") + c.SetInvalidParamWithErr("reaction", jsonErr) return } @@ -47,7 +47,7 @@ func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(re); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/remote_cluster.go b/api4/remote_cluster.go index 9b34fcc7c5..d0956a38a9 100644 --- a/api4/remote_cluster.go +++ b/api4/remote_cluster.go @@ -32,7 +32,7 @@ func remoteClusterPing(c *Context, w http.ResponseWriter, r *http.Request) { var frame model.RemoteClusterFrame if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("remoteClusterPing", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -78,7 +78,7 @@ func remoteClusterAcceptMessage(c *Context, w http.ResponseWriter, r *http.Reque var frame model.RemoteClusterFrame if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("remoteClusterAcceptMessage", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -124,7 +124,7 @@ func remoteClusterConfirmInvite(c *Context, w http.ResponseWriter, r *http.Reque var frame model.RemoteClusterFrame if jsonErr := json.NewDecoder(r.Body).Decode(&frame); jsonErr != nil { - c.Err = model.NewAppError("remoteClusterConfirmInvite", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("remoteClusterConfirmInvite", "api.unmarshal_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } @@ -216,7 +216,7 @@ func uploadRemoteData(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(info); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/role.go b/api4/role.go index c9ebc5577d..f9ea2dda90 100644 --- a/api4/role.go +++ b/api4/role.go @@ -60,7 +60,7 @@ func getRole(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(role); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -77,7 +77,7 @@ func getRoleByName(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(role); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -117,7 +117,7 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.RolePatch if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("role") + c.SetInvalidParamWithErr("role", jsonErr) return } @@ -214,6 +214,6 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(role); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/saml.go b/api4/saml.go index 9305550c79..f102870be6 100644 --- a/api4/saml.go +++ b/api4/saml.go @@ -232,7 +232,7 @@ func getSamlCertificateStatus(c *Context, w http.ResponseWriter, r *http.Request status := c.App.GetSamlCertificateStatus() if err := json.NewEncoder(w).Encode(status); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -256,7 +256,7 @@ func getSamlMetadataFromIdp(c *Context, w http.ResponseWriter, r *http.Request) } if err := json.NewEncoder(w).Encode(metadata); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -273,7 +273,7 @@ func resetAuthDataToEmail(c *Context, w http.ResponseWriter, r *http.Request) { var params *ResetAuthDataParams jsonErr := json.NewDecoder(r.Body).Decode(¶ms) if jsonErr != nil { - c.Err = model.NewAppError("resetAuthDataToEmail", "model.utils.decode_json.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("resetAuthDataToEmail", "model.utils.decode_json.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } numAffected, appErr := c.App.ResetSamlAuthDataToEmail(params.IncludeDeleted, params.DryRun, params.SpecifiedUserIDs) @@ -281,6 +281,14 @@ func resetAuthDataToEmail(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = appErr return } - b, _ := json.Marshal(map[string]any{"num_affected": numAffected}) - w.Write(b) + + n := struct { + NumAffected int `json:"num_affected"` + }{ + NumAffected: numAffected, + } + + if err := json.NewEncoder(w).Encode(n); err != nil { + c.Logger.Warn("Error writing response", mlog.Err(err)) + } } diff --git a/api4/scheme.go b/api4/scheme.go index 210b83fbe1..200d8f554d 100644 --- a/api4/scheme.go +++ b/api4/scheme.go @@ -25,7 +25,7 @@ func (api *API) InitScheme() { func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { var scheme model.Scheme if jsonErr := json.NewDecoder(r.Body).Decode(&scheme); jsonErr != nil { - c.SetInvalidParam("scheme") + c.SetInvalidParamWithErr("scheme", jsonErr) return } @@ -55,7 +55,7 @@ func createScheme(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(returnedScheme); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -77,7 +77,7 @@ func getScheme(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(scheme); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -172,7 +172,7 @@ func getChannelsForScheme(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(channels); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -184,7 +184,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.SchemePatch if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("scheme") + c.SetInvalidParamWithErr("scheme", jsonErr) return } @@ -223,7 +223,7 @@ func patchScheme(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(scheme); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/status.go b/api4/status.go index 7dc865572b..5ecc754b9d 100644 --- a/api4/status.go +++ b/api4/status.go @@ -44,7 +44,7 @@ func getUserStatus(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(statusMap[0]); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -86,7 +86,7 @@ func updateUserStatus(c *Context, w http.ResponseWriter, r *http.Request) { var status model.Status if jsonErr := json.NewDecoder(r.Body).Decode(&status); jsonErr != nil { - c.SetInvalidParam("status") + c.SetInvalidParamWithErr("status", jsonErr) return } @@ -137,7 +137,7 @@ func updateUserCustomStatus(c *Context, w http.ResponseWriter, r *http.Request) var customStatus model.CustomStatus jsonErr := json.NewDecoder(r.Body).Decode(&customStatus) if jsonErr != nil || (customStatus.Emoji == "" && customStatus.Text == "") || !customStatus.AreDurationAndExpirationTimeValid() { - c.SetInvalidParam("custom_status") + c.SetInvalidParamWithErr("custom_status", jsonErr) return } @@ -193,7 +193,7 @@ func removeUserRecentCustomStatus(c *Context, w http.ResponseWriter, r *http.Req var recentCustomStatus model.CustomStatus if jsonErr := json.NewDecoder(r.Body).Decode(&recentCustomStatus); jsonErr != nil { - c.SetInvalidParam("recent_custom_status") + c.SetInvalidParamWithErr("recent_custom_status", jsonErr) return } diff --git a/api4/system.go b/api4/system.go index 2617ed03e5..d35a2068c8 100644 --- a/api4/system.go +++ b/api4/system.go @@ -271,7 +271,7 @@ func getAudits(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.AddEventParameter("audits_per_page", c.Params.LogsPerPage) if err := json.NewEncoder(w).Encode(audits); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -410,7 +410,7 @@ func getAnalytics(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(rows); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -543,9 +543,9 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) { c.Err = model.NewAppError("pushNotificationAck", "api.push_notifications_ack.message.parse.app_error", nil, - jsonErr.Error(), + "", http.StatusBadRequest, - ) + ).Wrap(jsonErr) return } @@ -586,7 +586,7 @@ func pushNotificationAck(c *Context, w http.ResponseWriter, r *http.Request) { return } if err2 := json.NewEncoder(w).Encode(msg); err2 != nil { - mlog.Warn("Error while writing response", mlog.Err(err2)) + c.Logger.Warn("Error while writing response", mlog.Err(err2)) } } @@ -814,7 +814,7 @@ func sendWarnMetricAckEmail(c *Context, w http.ResponseWriter, r *http.Request) var ack model.SendWarnMetricAck if jsonErr := json.NewDecoder(r.Body).Decode(&ack); jsonErr != nil { - c.SetInvalidParam("ack") + c.SetInvalidParamWithErr("ack", jsonErr) return } @@ -916,7 +916,7 @@ func getOnboarding(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(firstAdminCompleteSetupObj); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/team.go b/api4/team.go index 33ede5115b..fac2d489c3 100644 --- a/api4/team.go +++ b/api4/team.go @@ -80,7 +80,7 @@ func (api *API) InitTeam() { func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.Team if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } team.Email = strings.ToLower(team.Email) @@ -131,7 +131,7 @@ func createTeam(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rteam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -154,7 +154,7 @@ func getTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), team) if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -177,7 +177,7 @@ func getTeamByName(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), team) if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -189,7 +189,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.Team if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } @@ -222,7 +222,7 @@ func updateTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeTeam(*c.AppContext.Session(), updatedTeam) if err := json.NewEncoder(w).Encode(updatedTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -234,7 +234,7 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.TeamPatch if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } @@ -266,7 +266,7 @@ func patchTeam(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("") if err := json.NewEncoder(w).Encode(patchedTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -325,7 +325,7 @@ func restoreTeam(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -380,7 +380,7 @@ func updateTeamPrivacy(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -413,7 +413,7 @@ func regenerateTeamInviteId(c *Context, w http.ResponseWriter, r *http.Request) c.LogAudit("") if err := json.NewEncoder(w).Encode(patchedTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -559,7 +559,7 @@ func getTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(team); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -687,7 +687,7 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { var err *model.AppError var member model.TeamMember if jsonErr := json.NewDecoder(r.Body).Decode(&member); jsonErr != nil { - c.Err = model.NewAppError("addTeamMember", "api.team.add_team_member.invalid_body.app_error", nil, "Error in model.TeamMemberFromJSON()", http.StatusBadRequest) + c.Err = model.NewAppError("addTeamMember", "api.team.add_team_member.invalid_body.app_error", nil, "Error in model.TeamMemberFromJSON()", http.StatusBadRequest).Wrap(jsonErr) return } if member.TeamId != c.Params.TeamId { @@ -763,7 +763,7 @@ func addTeamMember(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(tm); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -803,7 +803,7 @@ func addUserToTeamFromInvite(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(member); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -818,7 +818,7 @@ func addTeamMembers(c *Context, w http.ResponseWriter, r *http.Request) { var err *model.AppError var members []*model.TeamMember if jsonErr := json.NewDecoder(r.Body).Decode(&members); jsonErr != nil { - c.SetInvalidParam("members") + c.SetInvalidParamWithErr("members", jsonErr) return } @@ -991,7 +991,7 @@ func getTeamUnread(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(unreadTeam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1019,7 +1019,7 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(stats); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -1067,7 +1067,7 @@ func updateTeamMemberSchemeRoles(c *Context, w http.ResponseWriter, r *http.Requ var schemeRoles model.SchemeRoles if jsonErr := json.NewDecoder(r.Body).Decode(&schemeRoles); jsonErr != nil { - c.SetInvalidParam("scheme_roles") + c.SetInvalidParamWithErr("scheme_roles", jsonErr) return } @@ -1155,7 +1155,7 @@ func getAllTeams(c *Context, w http.ResponseWriter, r *http.Request) { func searchTeams(c *Context, w http.ResponseWriter, r *http.Request) { var props model.TeamSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("team_search") + c.SetInvalidParamWithErr("team_search", jsonErr) return } // Only system managers may use the ExcludePolicyConstrained field @@ -1476,7 +1476,7 @@ func inviteGuestsToChannels(c *Context, w http.ResponseWriter, r *http.Request) var guestsInvite model.GuestsInvite if jsonErr := json.NewDecoder(r.Body).Decode(&guestsInvite); jsonErr != nil { - c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, jsonErr.Error(), http.StatusBadRequest) + c.Err = model.NewAppError("Api4.inviteGuestsToChannels", "api.team.invite_guests_to_channels.invalid_body.app_error", nil, "", http.StatusBadRequest).Wrap(jsonErr) return } auditRec.AddEventParameter("guests_invite", guestsInvite) @@ -1695,7 +1695,7 @@ func updateTeamScheme(c *Context, w http.ResponseWriter, r *http.Request) { var p model.SchemeIDPatch if jsonErr := json.NewDecoder(r.Body).Decode(&p); jsonErr != nil { - c.SetInvalidParam("scheme_id") + c.SetInvalidParamWithErr("scheme_id", jsonErr) return } diff --git a/api4/team_local.go b/api4/team_local.go index 2f6aa488fa..29a93c6c0e 100644 --- a/api4/team_local.go +++ b/api4/team_local.go @@ -244,7 +244,7 @@ func normalizeDomains(domains string) []string { func localCreateTeam(c *Context, w http.ResponseWriter, r *http.Request) { var team model.Team if jsonErr := json.NewDecoder(r.Body).Decode(&team); jsonErr != nil { - c.SetInvalidParam("team") + c.SetInvalidParamWithErr("team", jsonErr) return } @@ -268,6 +268,6 @@ func localCreateTeam(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rteam); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/terms_of_service.go b/api4/terms_of_service.go index 2de763f0a2..53c5a61ccb 100644 --- a/api4/terms_of_service.go +++ b/api4/terms_of_service.go @@ -26,7 +26,7 @@ func getLatestTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) } if err := json.NewEncoder(w).Encode(termsOfService); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -67,11 +67,11 @@ func createTermsOfService(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(termsOfService); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } else { if err := json.NewEncoder(w).Encode(oldTermsOfService); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } auditRec.Success() diff --git a/api4/upload.go b/api4/upload.go index 312f468b6d..a96b1afc9e 100644 --- a/api4/upload.go +++ b/api4/upload.go @@ -31,7 +31,7 @@ func createUpload(c *Context, w http.ResponseWriter, r *http.Request) { var us model.UploadSession if jsonErr := json.NewDecoder(r.Body).Decode(&us); jsonErr != nil { - c.SetInvalidParam("upload") + c.SetInvalidParamWithErr("upload", jsonErr) return } @@ -74,7 +74,7 @@ func createUpload(c *Context, w http.ResponseWriter, r *http.Request) { auditRec.Success() w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rus); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -96,7 +96,7 @@ func getUpload(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(us); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -152,7 +152,7 @@ func uploadData(c *Context, w http.ResponseWriter, r *http.Request) { } if err := json.NewEncoder(w).Encode(info); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/user.go b/api4/user.go index 5749c145c0..56323550f4 100644 --- a/api4/user.go +++ b/api4/user.go @@ -108,7 +108,7 @@ func (api *API) InitUser() { func createUser(c *Context, w http.ResponseWriter, r *http.Request) { var user model.User if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -970,7 +970,7 @@ func getKnownUsers(c *Context, w http.ResponseWriter, r *http.Request) { func searchUsers(c *Context, w http.ResponseWriter, r *http.Request) { var props model.UserSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("") + c.SetInvalidParamWithErr("props", jsonErr) return } @@ -1168,7 +1168,7 @@ func updateUser(c *Context, w http.ResponseWriter, r *http.Request) { var user model.User if jsonErr := json.NewDecoder(r.Body).Decode(&user); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -1250,7 +1250,7 @@ func patchUser(c *Context, w http.ResponseWriter, r *http.Request) { var patch model.UserPatch if jsonErr := json.NewDecoder(r.Body).Decode(&patch); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -1515,7 +1515,7 @@ func updateUserAuth(c *Context, w http.ResponseWriter, r *http.Request) { var userAuth model.UserAuth if jsonErr := json.NewDecoder(r.Body).Decode(&userAuth); jsonErr != nil { - c.SetInvalidParam("user") + c.SetInvalidParamWithErr("user", jsonErr) return } @@ -2235,7 +2235,7 @@ func sendVerificationEmail(c *Context, w http.ResponseWriter, r *http.Request) { func switchAccountType(c *Context, w http.ResponseWriter, r *http.Request) { var switchRequest model.SwitchRequest if jsonErr := json.NewDecoder(r.Body).Decode(&switchRequest); jsonErr != nil { - c.SetInvalidParam("switch_request") + c.SetInvalidParamWithErr("switch_request", jsonErr) return } @@ -2297,7 +2297,7 @@ func createUserAccessToken(c *Context, w http.ResponseWriter, r *http.Request) { var accessToken model.UserAccessToken if jsonErr := json.NewDecoder(r.Body).Decode(&accessToken); jsonErr != nil { - c.SetInvalidParam("user_access_token") + c.SetInvalidParamWithErr("user_access_token", jsonErr) return } @@ -2344,7 +2344,7 @@ func searchUserAccessTokens(c *Context, w http.ResponseWriter, r *http.Request) var props model.UserAccessTokenSearch if jsonErr := json.NewDecoder(r.Body).Decode(&props); jsonErr != nil { - c.SetInvalidParam("user_access_token_search") + c.SetInvalidParamWithErr("user_access_token_search", jsonErr) return } @@ -2728,7 +2728,7 @@ func publishUserTyping(c *Context, w http.ResponseWriter, r *http.Request) { var typingRequest model.TypingRequest if jsonErr := json.NewDecoder(r.Body).Decode(&typingRequest); jsonErr != nil { - c.SetInvalidParam("typing_request") + c.SetInvalidParamWithErr("typing_request", jsonErr) return } diff --git a/api4/user_local.go b/api4/user_local.go index e093f2fdff..1b9c4fdf33 100644 --- a/api4/user_local.go +++ b/api4/user_local.go @@ -225,7 +225,7 @@ func localGetUser(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -308,7 +308,7 @@ func localGetUserByUsername(c *Context, w http.ResponseWriter, r *http.Request) c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -339,7 +339,7 @@ func localGetUserByEmail(c *Context, w http.ResponseWriter, r *http.Request) { c.App.SanitizeProfile(user, c.IsSystemAdmin()) w.Header().Set(model.HeaderEtagServer, etag) if err := json.NewEncoder(w).Encode(user); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/webhook.go b/api4/webhook.go index 3f19313bf6..744fc38263 100644 --- a/api4/webhook.go +++ b/api4/webhook.go @@ -30,7 +30,7 @@ func (api *API) InitWebhook() { func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.IncomingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("incoming_webhook") + c.SetInvalidParamWithErr("incoming_webhook", jsonErr) return } @@ -86,7 +86,7 @@ func createIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(incomingHook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -98,7 +98,7 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { var updatedHook model.IncomingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&updatedHook); jsonErr != nil { - c.SetInvalidParam("incoming_webhook") + c.SetInvalidParamWithErr("incoming_webhook", jsonErr) return } @@ -173,7 +173,7 @@ func updateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(incomingHook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -273,7 +273,7 @@ func getIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(hook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -342,7 +342,7 @@ func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { var updatedHook model.OutgoingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&updatedHook); jsonErr != nil { - c.SetInvalidParam("outgoing_webhook") + c.SetInvalidParamWithErr("outgoing_webhook", jsonErr) return } @@ -395,14 +395,14 @@ func updateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.OutgoingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("outgoing_webhook") + c.SetInvalidParamWithErr("outgoing_webhook", jsonErr) return } @@ -446,7 +446,7 @@ func createOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -545,7 +545,7 @@ func getOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { c.LogAudit("success") if err := json.NewEncoder(w).Encode(hook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } @@ -592,7 +592,7 @@ func regenOutgoingHookToken(c *Context, w http.ResponseWriter, r *http.Request) c.LogAudit("success") if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/api4/webhook_local.go b/api4/webhook_local.go index ae42ee4355..cadffbd41e 100644 --- a/api4/webhook_local.go +++ b/api4/webhook_local.go @@ -29,7 +29,7 @@ func (api *API) InitWebhookLocal() { func localCreateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.IncomingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("incoming_webhook") + c.SetInvalidParamWithErr("incoming_webhook", jsonErr) return } @@ -68,14 +68,14 @@ func localCreateIncomingHook(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(incomingHook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } func localCreateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) { var hook model.OutgoingWebhook if jsonErr := json.NewDecoder(r.Body).Decode(&hook); jsonErr != nil { - c.SetInvalidParam("outgoing_webhook") + c.SetInvalidParamWithErr("outgoing_webhook", jsonErr) return } @@ -109,6 +109,6 @@ func localCreateOutgoingHook(c *Context, w http.ResponseWriter, r *http.Request) w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(rhook); err != nil { - mlog.Warn("Error while writing response", mlog.Err(err)) + c.Logger.Warn("Error while writing response", mlog.Err(err)) } } diff --git a/app/plugin_api_test.go b/app/plugin_api_test.go index 00b61d1976..03cfce39bb 100644 --- a/app/plugin_api_test.go +++ b/app/plugin_api_test.go @@ -547,7 +547,7 @@ func TestPluginAPIUserCustomStatus(t *testing.T) { custom.Text = "" err = api.UpdateUserCustomStatus(user1.Id, custom) assert.NotNil(t, err) - assert.Equal(t, err.Error(), "SetCustomStatus: Failed to update the custom status. Please add either emoji or custom text status or both., ") + assert.Equal(t, err.Error(), "SetCustomStatus: Failed to update the custom status. Please add either emoji or custom text status or both.") // Remove custom status err = api.RemoveUserCustomStatus(user1.Id) @@ -889,7 +889,7 @@ func TestPluginAPIInstallPlugin(t *testing.T) { _, appErr := api.InstallPlugin(bytes.NewReader(tarData), true) assert.NotNil(t, appErr, "should not allow upload if upload disabled") - assert.Equal(t, appErr.Error(), "installPlugin: Plugins and/or plugin uploads have been disabled., ") + assert.Equal(t, appErr.Error(), "installPlugin: Plugins and/or plugin uploads have been disabled.") th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PluginSettings.Enable = true diff --git a/app/plugin_test.go b/app/plugin_test.go index a5346e270f..d5b21aefe5 100644 --- a/app/plugin_test.go +++ b/app/plugin_test.go @@ -453,7 +453,7 @@ func TestGetPluginStatusesDisabled(t *testing.T) { _, err := th.App.GetPluginStatuses() require.NotNil(t, err) - require.EqualError(t, err, "GetPluginStatuses: Plugins have been disabled. Please check your logs for details., ") + require.EqualError(t, err, "GetPluginStatuses: Plugins have been disabled. Please check your logs for details.") } func TestGetPluginStatuses(t *testing.T) { diff --git a/model/utils.go b/model/utils.go index 82c5e0953a..8d93015c57 100644 --- a/model/utils.go +++ b/model/utils.go @@ -10,7 +10,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net" "net/http" "net/mail" @@ -218,10 +217,32 @@ type AppError struct { Where string `json:"-"` // The function where it happened in the form of Struct.Func IsOAuth bool `json:"is_oauth,omitempty"` // Whether the error is OAuth specific params map[string]any + wrapped error } func (er *AppError) Error() string { - return er.Where + ": " + er.Message + ", " + er.DetailedError + var sb strings.Builder + + // render the error information + sb.WriteString(er.Where) + sb.WriteString(": ") + sb.WriteString(er.Message) + + // only render the detailed error when it's present + if er.DetailedError != "" { + sb.WriteString(", ") + sb.WriteString(er.DetailedError) + } + + // render all wrapped errors + err := er.wrapped + for err != nil { + sb.WriteString(", ") + sb.WriteString(err.Error()) + err = errors.Unwrap(err) + } + + return sb.String() } func (er *AppError) Translate(T i18n.TranslateFunc) { @@ -249,10 +270,19 @@ func (er *AppError) ToJSON() string { return string(b) } +func (er *AppError) Unwrap() error { + return er.wrapped +} + +func (er *AppError) Wrap(err error) *AppError { + er.wrapped = err + return er +} + // AppErrorFromJSON will decode the input and return an AppError func AppErrorFromJSON(data io.Reader) *AppError { str := "" - bytes, rerr := ioutil.ReadAll(data) + bytes, rerr := io.ReadAll(data) if rerr != nil { str = rerr.Error() } else { @@ -269,14 +299,15 @@ func AppErrorFromJSON(data io.Reader) *AppError { } func NewAppError(where string, id string, params map[string]any, details string, status int) *AppError { - ap := &AppError{} - ap.Id = id - ap.params = params - ap.Message = id - ap.Where = where - ap.DetailedError = details - ap.StatusCode = status - ap.IsOAuth = false + ap := &AppError{ + Id: id, + params: params, + Message: id, + Where: where, + DetailedError: details, + StatusCode: status, + IsOAuth: false, + } ap.Translate(translateFunc) return ap } diff --git a/model/utils_test.go b/model/utils_test.go index b81556d9d5..9ac33e39c1 100644 --- a/model/utils_test.go +++ b/model/utils_test.go @@ -85,6 +85,33 @@ func TestAppErrorJunk(t *testing.T) { require.Equal(t, "body: This is a broken test", rerr.DetailedError) } +func TestAppErrorRender(t *testing.T) { + t.Run("Minimal", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "", http.StatusTeapot) + assert.EqualError(t, aerr, "here: message") + }) + + t.Run("Detailed", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "details", http.StatusTeapot) + assert.EqualError(t, aerr, "here: message, details") + }) + + t.Run("Wrapped", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "", http.StatusTeapot).Wrap(fmt.Errorf("my error")) + assert.EqualError(t, aerr, "here: message, my error") + }) + + t.Run("WrappedMultiple", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "", http.StatusTeapot).Wrap(fmt.Errorf("my error (%w)", fmt.Errorf("inner error"))) + assert.EqualError(t, aerr, "here: message, my error (inner error), inner error") + }) + + t.Run("DetailedWrappedMultiple", func(t *testing.T) { + aerr := NewAppError("here", "message", nil, "details", http.StatusTeapot).Wrap(fmt.Errorf("my error (%w)", fmt.Errorf("inner error"))) + assert.EqualError(t, aerr, "here: message, details, my error (inner error), inner error") + }) +} + func TestCopyStringMap(t *testing.T) { itemKey := "item1" originalMap := make(map[string]string) diff --git a/shared/mail/inbucket.go b/shared/mail/inbucket.go index 42805f69a6..3bd8134ba6 100644 --- a/shared/mail/inbucket.go +++ b/shared/mail/inbucket.go @@ -74,11 +74,8 @@ func GetMailBox(email string) (results JSONMessageHeaderInbucket, err error) { var record JSONMessageHeaderInbucket err = json.NewDecoder(resp.Body).Decode(&record) - switch { - case err == io.EOF: - return nil, fmt.Errorf("error: %s", err) - case err != nil: - return nil, fmt.Errorf("error: %s", err) + if err != nil { + return nil, fmt.Errorf("error: %w", err) } if len(record) == 0 { return nil, fmt.Errorf("no mailbox") diff --git a/store/storetest/team_store.go b/store/storetest/team_store.go index 3df3096336..ad9bcb4f6a 100644 --- a/store/storetest/team_store.go +++ b/store/storetest/team_store.go @@ -1385,7 +1385,7 @@ func testTeamSaveMember(t *testing.T, ss store.Store) { member := &model.TeamMember{TeamId: "wrong", UserId: u1.Id} _, nErr := ss.Team().SaveMember(member, -1) require.Error(t, nErr) - require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error, ", nErr.Error()) + require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error", nErr.Error()) }) t.Run("too many members", func(t *testing.T) { @@ -1726,7 +1726,7 @@ func testTeamSaveMultipleMembers(t *testing.T, ss store.Store) { m2 := &model.TeamMember{TeamId: model.NewId(), UserId: u2.Id} _, nErr := ss.Team().SaveMultipleMembers([]*model.TeamMember{m1, m2}, -1) require.Error(t, nErr) - require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error, ", nErr.Error()) + require.Equal(t, "TeamMember.IsValid: model.team_member.is_valid.team_id.app_error", nErr.Error()) }) t.Run("too many members in one team", func(t *testing.T) { diff --git a/testlib/assertions.go b/testlib/assertions.go index 5b6afd7a97..a7ec27cdaa 100644 --- a/testlib/assertions.go +++ b/testlib/assertions.go @@ -20,6 +20,7 @@ func AssertLog(t *testing.T, logs io.Reader, level, message string) { if err := dec.Decode(&log); err == io.EOF { break } else if err != nil { + t.Logf("Error decoding log entry: %s", err) continue } @@ -42,6 +43,7 @@ func AssertNoLog(t *testing.T, logs io.Reader, level, message string) { if err := dec.Decode(&log); err == io.EOF { break } else if err != nil { + t.Logf("Error decoding log entry: %s", err) continue } diff --git a/web/context.go b/web/context.go index c573e8c105..de02d18c03 100644 --- a/web/context.go +++ b/web/context.go @@ -221,6 +221,10 @@ func (c *Context) SetInvalidParam(parameter string) { c.Err = NewInvalidParamError(parameter) } +func (c *Context) SetInvalidParamWithErr(parameter string, err error) { + c.Err = NewInvalidParamError(parameter).Wrap(err) +} + func (c *Context) SetInvalidURLParam(parameter string) { c.Err = NewInvalidURLParamError(parameter) } @@ -269,10 +273,12 @@ func NewInvalidParamError(parameter string) *model.AppError { err := model.NewAppError("Context", "api.context.invalid_body_param.app_error", map[string]any{"Name": parameter}, "", http.StatusBadRequest) return err } + func NewInvalidURLParamError(parameter string) *model.AppError { err := model.NewAppError("Context", "api.context.invalid_url_param.app_error", map[string]any{"Name": parameter}, "", http.StatusBadRequest) return err } + func NewServerBusyError() *model.AppError { err := model.NewAppError("Context", "api.context.server_busy.app_error", nil, "", http.StatusServiceUnavailable) return err