diff --git a/app/emoji.go b/app/emoji.go index bdc60c5789..6fe409b0a6 100644 --- a/app/emoji.go +++ b/app/emoji.go @@ -5,7 +5,10 @@ package app import ( "bytes" + "errors" + "fmt" "image" + "image/color/palette" "image/draw" "image/gif" _ "image/jpeg" @@ -15,11 +18,10 @@ import ( "net/http" "path" - "image/color/palette" - "github.com/disintegration/imaging" "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/store" "github.com/mattermost/mattermost-server/v5/utils" ) @@ -70,7 +72,7 @@ func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartIma emoji, err := a.Srv().Store.Emoji().Save(emoji) if err != nil { - return nil, err + return nil, model.NewAppError("CreateEmoji", "app.emoji.create.internal_error", nil, err.Error(), http.StatusInternalServerError) } message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_EMOJI_ADDED, "", "", "", nil) @@ -80,7 +82,12 @@ func (a *App) CreateEmoji(sessionUserId string, emoji *model.Emoji, multiPartIma } func (a *App) GetEmojiList(page, perPage int, sort string) ([]*model.Emoji, *model.AppError) { - return a.Srv().Store.Emoji().GetList(page*perPage, perPage, sort) + list, err := a.Srv().Store.Emoji().GetList(page*perPage, perPage, sort) + if err != nil { + return nil, model.NewAppError("GetEmojiList", "app.emoji.get_list.internal_error", nil, err.Error(), http.StatusInternalServerError) + } + + return list, nil } func (a *App) UploadEmojiImage(id string, imageData *multipart.FileHeader) *model.AppError { @@ -158,7 +165,13 @@ func (a *App) UploadEmojiImage(id string, imageData *multipart.FileHeader) *mode func (a *App) DeleteEmoji(emoji *model.Emoji) *model.AppError { if err := a.Srv().Store.Emoji().Delete(emoji, model.GetMillis()); err != nil { - return err + var nfErr *store.ErrNotFound + switch { + case errors.As(err, &nfErr): + return model.NewAppError("DeleteEmoji", "app.emoji.delete.no_results", nil, "id="+emoji.Id+", err="+err.Error(), http.StatusNotFound) + default: + return model.NewAppError("DeleteEmoji", "app.emoji.delete.app_error", nil, "id="+emoji.Id+", err="+err.Error(), http.StatusInternalServerError) + } } a.deleteEmojiImage(emoji.Id) @@ -175,19 +188,41 @@ func (a *App) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) { return nil, model.NewAppError("GetEmoji", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) } - return a.Srv().Store.Emoji().Get(emojiId, false) + emoji, err := a.Srv().Store.Emoji().Get(emojiId, false) + if err != nil { + var nfErr *store.ErrNotFound + switch { + case errors.As(err, &nfErr): + return emoji, model.NewAppError("GetEmoji", "app.emoji.get.no_result", nil, err.Error(), http.StatusNotFound) + default: + return emoji, model.NewAppError("GetEmoji", "app.emoji.get.app_error", nil, err.Error(), http.StatusInternalServerError) + } + } + + return emoji, nil } func (a *App) GetEmojiByName(emojiName string) (*model.Emoji, *model.AppError) { if !*a.Config().ServiceSettings.EnableCustomEmoji { - return nil, model.NewAppError("GetEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmojiByName", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) } if len(*a.Config().FileSettings.DriverName) == 0 { - return nil, model.NewAppError("GetEmoji", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) + return nil, model.NewAppError("GetEmojiByName", "api.emoji.storage.app_error", nil, "", http.StatusNotImplemented) } - return a.Srv().Store.Emoji().GetByName(emojiName, true) + emoji, err := a.Srv().Store.Emoji().GetByName(emojiName, true) + if err != nil { + var nfErr *store.ErrNotFound + switch { + case errors.As(err, &nfErr): + return emoji, model.NewAppError("GetEmojiByName", "app.emoji.get_by_name.no_result", nil, err.Error(), http.StatusNotFound) + default: + return emoji, model.NewAppError("GetEmojiByName", "app.emoji.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError) + } + } + + return emoji, nil } func (a *App) GetMultipleEmojiByName(names []string) ([]*model.Emoji, *model.AppError) { @@ -195,13 +230,24 @@ func (a *App) GetMultipleEmojiByName(names []string) ([]*model.Emoji, *model.App return nil, model.NewAppError("GetMultipleEmojiByName", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) } - return a.Srv().Store.Emoji().GetMultipleByName(names) + emoji, err := a.Srv().Store.Emoji().GetMultipleByName(names) + if err != nil { + return nil, model.NewAppError("GetMultipleEmojiByName", "app.emoji.get_by_name.app_error", nil, fmt.Sprintf("names=%v, %v", names, err.Error()), http.StatusInternalServerError) + } + + return emoji, nil } func (a *App) GetEmojiImage(emojiId string) ([]byte, string, *model.AppError) { _, storeErr := a.Srv().Store.Emoji().Get(emojiId, true) if storeErr != nil { - return nil, "", storeErr + var nfErr *store.ErrNotFound + switch { + case errors.As(storeErr, &nfErr): + return nil, "", model.NewAppError("GetEmojiImage", "app.emoji.get.no_result", nil, storeErr.Error(), http.StatusNotFound) + default: + return nil, "", model.NewAppError("GetEmojiImage", "app.emoji.get.app_error", nil, storeErr.Error(), http.StatusInternalServerError) + } } img, appErr := a.ReadFile(getEmojiImagePath(emojiId)) @@ -222,7 +268,12 @@ func (a *App) SearchEmoji(name string, prefixOnly bool, limit int) ([]*model.Emo return nil, model.NewAppError("SearchEmoji", "api.emoji.disabled.app_error", nil, "", http.StatusNotImplemented) } - return a.Srv().Store.Emoji().Search(name, prefixOnly, limit) + list, err := a.Srv().Store.Emoji().Search(name, prefixOnly, limit) + if err != nil { + return nil, model.NewAppError("SearchEmoji", "app.emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) + } + + return list, nil } // GetEmojiStaticUrl returns a relative static URL for system default emojis, @@ -237,7 +288,13 @@ func (a *App) GetEmojiStaticUrl(emojiName string) (string, *model.AppError) { if emoji, err := a.Srv().Store.Emoji().GetByName(emojiName, true); err == nil { return path.Join(subPath, "/api/v4/emoji", emoji.Id, "image"), nil } else { - return "", err + var nfErr *store.ErrNotFound + switch { + case errors.As(err, &nfErr): + return "", model.NewAppError("GetEmojiStaticUrl", "app.emoji.get_by_name.no_result", nil, err.Error(), http.StatusNotFound) + default: + return "", model.NewAppError("GetEmojiStaticUrl", "app.emoji.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError) + } } } diff --git a/app/import_functions.go b/app/import_functions.go index b9ac6b83a9..cd84105bd6 100644 --- a/app/import_functions.go +++ b/app/import_functions.go @@ -6,6 +6,7 @@ package app import ( "bytes" "crypto/sha1" + "errors" "io" "net/http" "os" @@ -1580,9 +1581,12 @@ func (a *App) importEmoji(data *EmojiImportData, dryRun bool) *model.AppError { var emoji *model.Emoji - emoji, appError := a.Srv().Store.Emoji().GetByName(*data.Name, true) - if appError != nil && appError.StatusCode != http.StatusNotFound { - return appError + emoji, err := a.Srv().Store.Emoji().GetByName(*data.Name, true) + if err != nil { + var nfErr *store.ErrNotFound + if !errors.As(err, &nfErr) { + return model.NewAppError("importEmoji", "app.emoji.get_by_name.app_error", nil, err.Error(), http.StatusInternalServerError) + } } alreadyExists := emoji != nil @@ -1605,7 +1609,7 @@ func (a *App) importEmoji(data *EmojiImportData, dryRun bool) *model.AppError { if !alreadyExists { if _, err := a.Srv().Store.Emoji().Save(emoji); err != nil { - return err + return model.NewAppError("importEmoji", "api.emoji.create.internal_error", nil, err.Error(), http.StatusBadRequest) } } diff --git a/app/import_functions_test.go b/app/import_functions_test.go index 13ce82a55e..969e4966b2 100644 --- a/app/import_functions_test.go +++ b/app/import_functions_test.go @@ -3449,9 +3449,9 @@ func TestImportImportEmoji(t *testing.T) { err := th.App.importEmoji(&data, true) assert.NotNil(t, err, "Invalid emoji should have failed dry run") - emoji, err := th.App.Srv().Store.Emoji().GetByName(*data.Name, true) + emoji, nErr := th.App.Srv().Store.Emoji().GetByName(*data.Name, true) assert.Nil(t, emoji, "Emoji should not have been imported") - assert.NotNil(t, err) + assert.NotNil(t, nErr) data.Image = ptrStr(testImage) err = th.App.importEmoji(&data, true) @@ -3469,9 +3469,9 @@ func TestImportImportEmoji(t *testing.T) { err = th.App.importEmoji(&data, false) assert.Nil(t, err, "Valid emoji should have succeeded apply mode") - emoji, err = th.App.Srv().Store.Emoji().GetByName(*data.Name, true) + emoji, nErr = th.App.Srv().Store.Emoji().GetByName(*data.Name, true) assert.NotNil(t, emoji, "Emoji should have been imported") - assert.Nil(t, err, "Emoji should have been imported without any error") + assert.Nil(t, nErr, "Emoji should have been imported without any error") err = th.App.importEmoji(&data, false) assert.Nil(t, err, "Second run should have succeeded apply mode") diff --git a/i18n/en.json b/i18n/en.json index 8c73abfe18..9b48530670 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1216,6 +1216,10 @@ "id": "api.emoji.create.duplicate.app_error", "translation": "Unable to create emoji. Another emoji with the same name already exists." }, + { + "id": "api.emoji.create.internal_error", + "translation": "server_error: Encountered internal server error creating the emoji." + }, { "id": "api.emoji.create.other_user.app_error", "translation": "Invalid user id." @@ -3018,6 +3022,38 @@ "id": "app.cluster.404.app_error", "translation": "Cluster API endpoint not found." }, + { + "id": "app.emoji.create.internal_error", + "translation": "Unable to save emoji." + }, + { + "id": "app.emoji.delete.app_error", + "translation": "Unable to delete the emoji." + }, + { + "id": "app.emoji.delete.no_results", + "translation": "We couldn’t find the emoji to delete." + }, + { + "id": "app.emoji.get.app_error", + "translation": "Unable to get the emoji." + }, + { + "id": "app.emoji.get.no_result", + "translation": "We couldn’t find the emoji." + }, + { + "id": "app.emoji.get_by_name.app_error", + "translation": "Unable to get the emoji." + }, + { + "id": "app.emoji.get_by_name.no_result", + "translation": "We couldn’t find the emoji." + }, + { + "id": "app.emoji.get_list.internal_error", + "translation": "Unable to get the emoji." + }, { "id": "app.export.export_custom_emoji.copy_emoji_images.error", "translation": "Unable to copy custom emoji images" @@ -6422,30 +6458,6 @@ "id": "store.sql_compliance.save.saving.app_error", "translation": "We encountered an error saving the compliance report." }, - { - "id": "store.sql_emoji.delete.app_error", - "translation": "Unable to delete the emoji." - }, - { - "id": "store.sql_emoji.delete.no_results", - "translation": "We couldn’t find the emoji to delete." - }, - { - "id": "store.sql_emoji.get.app_error", - "translation": "Unable to get the emoji." - }, - { - "id": "store.sql_emoji.get_all.app_error", - "translation": "Unable to get the emoji." - }, - { - "id": "store.sql_emoji.get_by_name.app_error", - "translation": "Unable to get the emoji." - }, - { - "id": "store.sql_emoji.save.app_error", - "translation": "Unable to save the emoji." - }, { "id": "store.sql_file_info.PermanentDeleteByUser.app_error", "translation": "Unable to delete attachments of the user." diff --git a/store/localcachelayer/emoji_layer.go b/store/localcachelayer/emoji_layer.go index 22e01293f5..7aaeb4062c 100644 --- a/store/localcachelayer/emoji_layer.go +++ b/store/localcachelayer/emoji_layer.go @@ -29,7 +29,7 @@ func (es *LocalCacheEmojiStore) handleClusterInvalidateEmojiIdByName(msg *model. } } -func (es LocalCacheEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (es LocalCacheEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, error) { if allowFromCache { if emoji, ok := es.getFromCacheById(id); ok { return emoji, nil @@ -45,7 +45,7 @@ func (es LocalCacheEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji return emoji, err } -func (es LocalCacheEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (es LocalCacheEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, error) { if id, ok := model.GetSystemEmojiId(name); ok { return es.Get(id, allowFromCache) } @@ -65,7 +65,7 @@ func (es LocalCacheEmojiStore) GetByName(name string, allowFromCache bool) (*mod return emoji, err } -func (es LocalCacheEmojiStore) Delete(emoji *model.Emoji, time int64) *model.AppError { +func (es LocalCacheEmojiStore) Delete(emoji *model.Emoji, time int64) error { err := es.EmojiStore.Delete(emoji, time) if err == nil { diff --git a/store/opentracing_layer.go b/store/opentracing_layer.go index 0e9c8a01fb..ca6c4b6aa6 100644 --- a/store/opentracing_layer.go +++ b/store/opentracing_layer.go @@ -2506,7 +2506,7 @@ func (s *OpenTracingLayerComplianceStore) Update(compliance *model.Compliance) ( return resultVar0, resultVar1 } -func (s *OpenTracingLayerEmojiStore) Delete(emoji *model.Emoji, time int64) *model.AppError { +func (s *OpenTracingLayerEmojiStore) Delete(emoji *model.Emoji, time int64) error { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.Delete") s.Root.Store.SetContext(newCtx) @@ -2524,7 +2524,7 @@ func (s *OpenTracingLayerEmojiStore) Delete(emoji *model.Emoji, time int64) *mod return resultVar0 } -func (s *OpenTracingLayerEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (s *OpenTracingLayerEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.Get") s.Root.Store.SetContext(newCtx) @@ -2542,7 +2542,7 @@ func (s *OpenTracingLayerEmojiStore) Get(id string, allowFromCache bool) (*model return resultVar0, resultVar1 } -func (s *OpenTracingLayerEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (s *OpenTracingLayerEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.GetByName") s.Root.Store.SetContext(newCtx) @@ -2560,7 +2560,7 @@ func (s *OpenTracingLayerEmojiStore) GetByName(name string, allowFromCache bool) return resultVar0, resultVar1 } -func (s *OpenTracingLayerEmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoji, *model.AppError) { +func (s *OpenTracingLayerEmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoji, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.GetList") s.Root.Store.SetContext(newCtx) @@ -2578,7 +2578,7 @@ func (s *OpenTracingLayerEmojiStore) GetList(offset int, limit int, sort string) return resultVar0, resultVar1 } -func (s *OpenTracingLayerEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, *model.AppError) { +func (s *OpenTracingLayerEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.GetMultipleByName") s.Root.Store.SetContext(newCtx) @@ -2596,7 +2596,7 @@ func (s *OpenTracingLayerEmojiStore) GetMultipleByName(names []string) ([]*model return resultVar0, resultVar1 } -func (s *OpenTracingLayerEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *model.AppError) { +func (s *OpenTracingLayerEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.Save") s.Root.Store.SetContext(newCtx) @@ -2614,7 +2614,7 @@ func (s *OpenTracingLayerEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *mo return resultVar0, resultVar1 } -func (s *OpenTracingLayerEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) { +func (s *OpenTracingLayerEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "EmojiStore.Search") s.Root.Store.SetContext(newCtx) diff --git a/store/sqlstore/emoji_store.go b/store/sqlstore/emoji_store.go index 136b609fd3..3063086551 100644 --- a/store/sqlstore/emoji_store.go +++ b/store/sqlstore/emoji_store.go @@ -6,11 +6,12 @@ package sqlstore import ( "database/sql" "fmt" - "net/http" "github.com/mattermost/mattermost-server/v5/einterfaces" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/store" + + "github.com/pkg/errors" ) type SqlEmojiStore struct { @@ -43,28 +44,28 @@ func (es SqlEmojiStore) createIndexesIfNotExists() { es.CreateIndexIfNotExists("idx_emoji_name", "Emoji", "Name") } -func (es SqlEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, error) { emoji.PreSave() if err := emoji.IsValid(); err != nil { return nil, err } if err := es.GetMaster().Insert(emoji); err != nil { - return nil, model.NewAppError("SqlEmojiStore.Save", "store.sql_emoji.save.app_error", nil, "id="+emoji.Id+", "+err.Error(), http.StatusInternalServerError) + return nil, errors.Wrap(err, "error saving emoji") } return emoji, nil } -func (es SqlEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, error) { return es.getBy("Id", id, allowFromCache) } -func (es SqlEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, error) { return es.getBy("Name", name, allowFromCache) } -func (es SqlEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, error) { keys, params := MapStringsToQueryParams(names, "Emoji") var emojis []*model.Emoji @@ -77,12 +78,12 @@ func (es SqlEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, *mode WHERE Name IN `+keys+` AND DeleteAt = 0`, params); err != nil { - return nil, model.NewAppError("SqlEmojiStore.GetByName", "store.sql_emoji.get_by_name.app_error", nil, fmt.Sprintf("names=%v, %v", names, err.Error()), http.StatusInternalServerError) + return nil, errors.Wrapf(err, "error getting emoji by names %v", names) } return emojis, nil } -func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji, error) { var emoji []*model.Emoji query := "SELECT * FROM Emoji WHERE DeleteAt = 0" @@ -94,12 +95,12 @@ func (es SqlEmojiStore) GetList(offset, limit int, sort string) ([]*model.Emoji, query += " LIMIT :Limit OFFSET :Offset" if _, err := es.GetReplica().Select(&emoji, query, map[string]interface{}{"Offset": offset, "Limit": limit}); err != nil { - return nil, model.NewAppError("SqlEmojiStore.GetList", "store.sql_emoji.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) + return nil, errors.Wrap(err, "could not get list of emojis") } return emoji, nil } -func (es SqlEmojiStore) Delete(emoji *model.Emoji, time int64) *model.AppError { +func (es SqlEmojiStore) Delete(emoji *model.Emoji, time int64) error { if sqlResult, err := es.GetMaster().Exec( `UPDATE Emoji @@ -109,15 +110,15 @@ func (es SqlEmojiStore) Delete(emoji *model.Emoji, time int64) *model.AppError { WHERE Id = :Id AND DeleteAt = 0`, map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": emoji.Id}); err != nil { - return model.NewAppError("SqlEmojiStore.Delete", "store.sql_emoji.delete.app_error", nil, "id="+emoji.Id+", err="+err.Error(), http.StatusInternalServerError) + return errors.Wrap(err, "could not delete emoji") } else if rows, _ := sqlResult.RowsAffected(); rows == 0 { - return model.NewAppError("SqlEmojiStore.Delete", "store.sql_emoji.delete.no_results", nil, "id="+emoji.Id, http.StatusBadRequest) + return store.NewErrNotFound("Emoji", emoji.Id) } return nil } -func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) { var emojis []*model.Emoji name = sanitizeSearchTerm(name, "\\") @@ -139,13 +140,13 @@ func (es SqlEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*mode AND DeleteAt = 0 ORDER BY Name LIMIT :Limit`, map[string]interface{}{"Name": term, "Limit": limit}); err != nil { - return nil, model.NewAppError("SqlEmojiStore.Search", "store.sql_emoji.get_by_name.app_error", nil, "name="+name+", "+err.Error(), http.StatusInternalServerError) + return nil, errors.Wrapf(err, "could not search emojis by name %s", name) } return emojis, nil } // getBy returns one active (not deleted) emoji, found by any one column (what/key). -func (es SqlEmojiStore) getBy(what string, key interface{}, addToCache bool) (*model.Emoji, *model.AppError) { +func (es SqlEmojiStore) getBy(what, key string, addToCache bool) (*model.Emoji, error) { var emoji *model.Emoji err := es.GetReplica().SelectOne(&emoji, @@ -155,15 +156,13 @@ func (es SqlEmojiStore) getBy(what string, key interface{}, addToCache bool) (*m Emoji WHERE `+what+` = :Key - AND DeleteAt = 0`, map[string]interface{}{"Key": key}) + AND DeleteAt = 0`, map[string]string{"Key": key}) if err != nil { - var status int if err == sql.ErrNoRows { - status = http.StatusNotFound - } else { - status = http.StatusInternalServerError + return nil, store.NewErrNotFound("Emoji", fmt.Sprintf("%s=%s", what, key)) } - return nil, model.NewAppError("SqlEmojiStore.GetByName", "store.sql_emoji.get.app_error", nil, "key="+fmt.Sprintf("%v", key)+", "+err.Error(), status) + + return nil, errors.Wrapf(err, "could not get emoji by %s with value %s", what, key) } return emoji, nil diff --git a/store/store.go b/store/store.go index f06405d329..5b0e1543aa 100644 --- a/store/store.go +++ b/store/store.go @@ -497,13 +497,13 @@ type TokenStore interface { } type EmojiStore interface { - Save(emoji *model.Emoji) (*model.Emoji, *model.AppError) - Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) - GetByName(name string, allowFromCache bool) (*model.Emoji, *model.AppError) - GetMultipleByName(names []string) ([]*model.Emoji, *model.AppError) - GetList(offset, limit int, sort string) ([]*model.Emoji, *model.AppError) - Delete(emoji *model.Emoji, time int64) *model.AppError - Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) + Save(emoji *model.Emoji) (*model.Emoji, error) + Get(id string, allowFromCache bool) (*model.Emoji, error) + GetByName(name string, allowFromCache bool) (*model.Emoji, error) + GetMultipleByName(names []string) ([]*model.Emoji, error) + GetList(offset, limit int, sort string) ([]*model.Emoji, error) + Delete(emoji *model.Emoji, time int64) error + Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) } type StatusStore interface { diff --git a/store/storetest/mocks/EmojiStore.go b/store/storetest/mocks/EmojiStore.go index 5d2b4a9a41..d0d45c6d08 100644 --- a/store/storetest/mocks/EmojiStore.go +++ b/store/storetest/mocks/EmojiStore.go @@ -15,23 +15,21 @@ type EmojiStore struct { } // Delete provides a mock function with given fields: emoji, time -func (_m *EmojiStore) Delete(emoji *model.Emoji, time int64) *model.AppError { +func (_m *EmojiStore) Delete(emoji *model.Emoji, time int64) error { ret := _m.Called(emoji, time) - var r0 *model.AppError - if rf, ok := ret.Get(0).(func(*model.Emoji, int64) *model.AppError); ok { + var r0 error + if rf, ok := ret.Get(0).(func(*model.Emoji, int64) error); ok { r0 = rf(emoji, time) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.AppError) - } + r0 = ret.Error(0) } return r0 } // Get provides a mock function with given fields: id, allowFromCache -func (_m *EmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (_m *EmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, error) { ret := _m.Called(id, allowFromCache) var r0 *model.Emoji @@ -43,20 +41,18 @@ func (_m *EmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model. } } - var r1 *model.AppError - if rf, ok := ret.Get(1).(func(string, bool) *model.AppError); ok { + var r1 error + if rf, ok := ret.Get(1).(func(string, bool) error); ok { r1 = rf(id, allowFromCache) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(*model.AppError) - } + r1 = ret.Error(1) } return r0, r1 } // GetByName provides a mock function with given fields: name, allowFromCache -func (_m *EmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (_m *EmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, error) { ret := _m.Called(name, allowFromCache) var r0 *model.Emoji @@ -68,20 +64,18 @@ func (_m *EmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, } } - var r1 *model.AppError - if rf, ok := ret.Get(1).(func(string, bool) *model.AppError); ok { + var r1 error + if rf, ok := ret.Get(1).(func(string, bool) error); ok { r1 = rf(name, allowFromCache) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(*model.AppError) - } + r1 = ret.Error(1) } return r0, r1 } // GetList provides a mock function with given fields: offset, limit, sort -func (_m *EmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoji, *model.AppError) { +func (_m *EmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoji, error) { ret := _m.Called(offset, limit, sort) var r0 []*model.Emoji @@ -93,20 +87,18 @@ func (_m *EmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoj } } - var r1 *model.AppError - if rf, ok := ret.Get(1).(func(int, int, string) *model.AppError); ok { + var r1 error + if rf, ok := ret.Get(1).(func(int, int, string) error); ok { r1 = rf(offset, limit, sort) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(*model.AppError) - } + r1 = ret.Error(1) } return r0, r1 } // GetMultipleByName provides a mock function with given fields: names -func (_m *EmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, *model.AppError) { +func (_m *EmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, error) { ret := _m.Called(names) var r0 []*model.Emoji @@ -118,20 +110,18 @@ func (_m *EmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, *model. } } - var r1 *model.AppError - if rf, ok := ret.Get(1).(func([]string) *model.AppError); ok { + var r1 error + if rf, ok := ret.Get(1).(func([]string) error); ok { r1 = rf(names) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(*model.AppError) - } + r1 = ret.Error(1) } return r0, r1 } // Save provides a mock function with given fields: emoji -func (_m *EmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *model.AppError) { +func (_m *EmojiStore) Save(emoji *model.Emoji) (*model.Emoji, error) { ret := _m.Called(emoji) var r0 *model.Emoji @@ -143,20 +133,18 @@ func (_m *EmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *model.AppError) { } } - var r1 *model.AppError - if rf, ok := ret.Get(1).(func(*model.Emoji) *model.AppError); ok { + var r1 error + if rf, ok := ret.Get(1).(func(*model.Emoji) error); ok { r1 = rf(emoji) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(*model.AppError) - } + r1 = ret.Error(1) } return r0, r1 } // Search provides a mock function with given fields: name, prefixOnly, limit -func (_m *EmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) { +func (_m *EmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) { ret := _m.Called(name, prefixOnly, limit) var r0 []*model.Emoji @@ -168,13 +156,11 @@ func (_m *EmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model. } } - var r1 *model.AppError - if rf, ok := ret.Get(1).(func(string, bool, int) *model.AppError); ok { + var r1 error + if rf, ok := ret.Get(1).(func(string, bool, int) error); ok { r1 = rf(name, prefixOnly, limit) } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(*model.AppError) - } + r1 = ret.Error(1) } return r0, r1 diff --git a/store/timer_layer.go b/store/timer_layer.go index 486e1ae33e..f82e4b7498 100644 --- a/store/timer_layer.go +++ b/store/timer_layer.go @@ -2304,7 +2304,7 @@ func (s *TimerLayerComplianceStore) Update(compliance *model.Compliance) (*model return resultVar0, resultVar1 } -func (s *TimerLayerEmojiStore) Delete(emoji *model.Emoji, time int64) *model.AppError { +func (s *TimerLayerEmojiStore) Delete(emoji *model.Emoji, time int64) error { start := timemodule.Now() resultVar0 := s.EmojiStore.Delete(emoji, time) @@ -2320,7 +2320,7 @@ func (s *TimerLayerEmojiStore) Delete(emoji *model.Emoji, time int64) *model.App return resultVar0 } -func (s *TimerLayerEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (s *TimerLayerEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji, error) { start := timemodule.Now() resultVar0, resultVar1 := s.EmojiStore.Get(id, allowFromCache) @@ -2336,7 +2336,7 @@ func (s *TimerLayerEmojiStore) Get(id string, allowFromCache bool) (*model.Emoji return resultVar0, resultVar1 } -func (s *TimerLayerEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, *model.AppError) { +func (s *TimerLayerEmojiStore) GetByName(name string, allowFromCache bool) (*model.Emoji, error) { start := timemodule.Now() resultVar0, resultVar1 := s.EmojiStore.GetByName(name, allowFromCache) @@ -2352,7 +2352,7 @@ func (s *TimerLayerEmojiStore) GetByName(name string, allowFromCache bool) (*mod return resultVar0, resultVar1 } -func (s *TimerLayerEmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoji, *model.AppError) { +func (s *TimerLayerEmojiStore) GetList(offset int, limit int, sort string) ([]*model.Emoji, error) { start := timemodule.Now() resultVar0, resultVar1 := s.EmojiStore.GetList(offset, limit, sort) @@ -2368,7 +2368,7 @@ func (s *TimerLayerEmojiStore) GetList(offset int, limit int, sort string) ([]*m return resultVar0, resultVar1 } -func (s *TimerLayerEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, *model.AppError) { +func (s *TimerLayerEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji, error) { start := timemodule.Now() resultVar0, resultVar1 := s.EmojiStore.GetMultipleByName(names) @@ -2384,7 +2384,7 @@ func (s *TimerLayerEmojiStore) GetMultipleByName(names []string) ([]*model.Emoji return resultVar0, resultVar1 } -func (s *TimerLayerEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *model.AppError) { +func (s *TimerLayerEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, error) { start := timemodule.Now() resultVar0, resultVar1 := s.EmojiStore.Save(emoji) @@ -2400,7 +2400,7 @@ func (s *TimerLayerEmojiStore) Save(emoji *model.Emoji) (*model.Emoji, *model.Ap return resultVar0, resultVar1 } -func (s *TimerLayerEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, *model.AppError) { +func (s *TimerLayerEmojiStore) Search(name string, prefixOnly bool, limit int) ([]*model.Emoji, error) { start := timemodule.Now() resultVar0, resultVar1 := s.EmojiStore.Search(name, prefixOnly, limit)