mirror of
https://github.com/mattermost/focalboard.git
synced 2025-01-11 18:13:52 +02:00
Standardize err not found (#2834)
* cleanup log levels * Standardize on model.IsErrNotFound instead of the mix of error checking done previously. * fix merge conflicts * fix comment typo * add description to asserts
This commit is contained in:
parent
99882bf197
commit
936cc820ab
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/focalboard/server/services/config"
|
||||
@ -13,7 +12,6 @@ import (
|
||||
"github.com/mattermost/focalboard/server/ws"
|
||||
|
||||
pluginapi "github.com/mattermost/mattermost-plugin-api"
|
||||
apierrors "github.com/mattermost/mattermost-plugin-api/errors"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
|
||||
@ -123,7 +121,3 @@ func (da *pluginAPIAdapter) GetChannelByID(channelID string) (*model.Channel, er
|
||||
func (da *pluginAPIAdapter) GetChannelMember(channelID string, userID string) (*model.ChannelMember, error) {
|
||||
return da.client.Channel.GetMember(channelID, userID)
|
||||
}
|
||||
|
||||
func (da *pluginAPIAdapter) IsErrNotFound(err error) bool {
|
||||
return errors.Is(err, apierrors.ErrNotFound)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
@ -17,7 +16,7 @@ var (
|
||||
|
||||
func (a *App) GetBoard(boardID string) (*model.Board, error) {
|
||||
board, err := a.store.GetBoard(boardID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
@ -214,7 +213,7 @@ func (a *App) PatchBoard(patch *model.BoardPatch, boardID, userID string) (*mode
|
||||
|
||||
func (a *App) DeleteBoard(boardID, userID string) error {
|
||||
board, err := a.store.GetBoard(boardID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
@ -246,7 +245,7 @@ func (a *App) GetMemberForBoard(boardID string, userID string) (*model.BoardMemb
|
||||
|
||||
func (a *App) AddMemberToBoard(member *model.BoardMember) (*model.BoardMember, error) {
|
||||
board, err := a.store.GetBoard(member.BoardID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
@ -254,7 +253,7 @@ func (a *App) AddMemberToBoard(member *model.BoardMember) (*model.BoardMember, e
|
||||
}
|
||||
|
||||
existingMembership, err := a.store.GetMemberForBoard(member.BoardID, member.UserID)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
if err != nil && !model.IsErrNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -276,7 +275,7 @@ func (a *App) AddMemberToBoard(member *model.BoardMember) (*model.BoardMember, e
|
||||
|
||||
func (a *App) UpdateBoardMember(member *model.BoardMember) (*model.BoardMember, error) {
|
||||
board, bErr := a.store.GetBoard(member.BoardID)
|
||||
if errors.Is(bErr, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(bErr) {
|
||||
return nil, nil
|
||||
}
|
||||
if bErr != nil {
|
||||
@ -284,7 +283,7 @@ func (a *App) UpdateBoardMember(member *model.BoardMember) (*model.BoardMember,
|
||||
}
|
||||
|
||||
oldMember, err := a.store.GetMemberForBoard(member.BoardID, member.UserID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
@ -331,7 +330,7 @@ func (a *App) isLastAdmin(userID, boardID string) (bool, error) {
|
||||
|
||||
func (a *App) DeleteBoardMember(boardID, userID string) error {
|
||||
board, bErr := a.store.GetBoard(boardID)
|
||||
if errors.Is(bErr, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(bErr) {
|
||||
return nil
|
||||
}
|
||||
if bErr != nil {
|
||||
@ -339,7 +338,7 @@ func (a *App) DeleteBoardMember(boardID, userID string) error {
|
||||
}
|
||||
|
||||
oldMember, err := a.store.GetMemberForBoard(boardID, userID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -1,15 +1,12 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
)
|
||||
|
||||
func (a *App) GetSharing(boardID string) (*model.Sharing, error) {
|
||||
sharing, err := a.store.GetSharing(boardID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -1,9 +1,6 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
@ -38,7 +35,7 @@ func (a *App) GetRootTeam() (*model.Team, error) {
|
||||
|
||||
func (a *App) GetTeam(id string) (*model.Team, error) {
|
||||
team, err := a.store.GetTeam(id)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -2,8 +2,6 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/config"
|
||||
"github.com/mattermost/focalboard/server/services/permissions"
|
||||
@ -49,7 +47,7 @@ func (a *Auth) GetSession(token string) (*model.Session, error) {
|
||||
// IsValidReadToken validates the read token for a board.
|
||||
func (a *Auth) IsValidReadToken(boardID string, readToken string) (bool, error) {
|
||||
sharing, err := a.store.GetSharing(boardID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return false, nil
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -10,9 +10,10 @@ import (
|
||||
mockpermissions "github.com/mattermost/focalboard/server/services/permissions/mocks"
|
||||
"github.com/mattermost/focalboard/server/services/store/mockstore"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
)
|
||||
|
||||
type TestHelper struct {
|
||||
|
49
server/model/error.go
Normal file
49
server/model/error.go
Normal file
@ -0,0 +1,49 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
apierrors "github.com/mattermost/mattermost-plugin-api/errors"
|
||||
)
|
||||
|
||||
// ErrNotFound is an error type that can be returned by store APIs when a query unexpectedly fetches no records.
|
||||
type ErrNotFound struct {
|
||||
resource string
|
||||
}
|
||||
|
||||
// NewErrNotFound creates a new ErrNotFound instance.
|
||||
func NewErrNotFound(resource string) *ErrNotFound {
|
||||
return &ErrNotFound{
|
||||
resource: resource,
|
||||
}
|
||||
}
|
||||
|
||||
func (nf *ErrNotFound) Error() string {
|
||||
return fmt.Sprintf("{%s} not found", nf.resource)
|
||||
}
|
||||
|
||||
// IsErrNotFound returns true if `err` is or wraps one of:
|
||||
// - model.ErrNotFound
|
||||
// - sql.ErrNoRows
|
||||
// - mattermost-plugin-api/errors/ErrNotFound.
|
||||
func IsErrNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// check if this is a sql.ErrNotFound
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if this is a model.ErrNotFound
|
||||
var nf *ErrNotFound
|
||||
if errors.As(err, &nf) {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if this is a plugin API error
|
||||
return errors.Is(err, apierrors.ErrNotFound)
|
||||
}
|
@ -15,5 +15,4 @@ import (
|
||||
type MentionDelivery interface {
|
||||
MentionDeliver(mentionedUser *mm_model.User, extract string, evt notify.BlockChangeEvent) (string, error)
|
||||
UserByUsername(mentionUsername string) (*mm_model.User, error)
|
||||
IsErrNotFound(err error) bool
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ func safeCallListener(listener MentionListener, userID string, evt notify.BlockC
|
||||
func (b *Backend) deliverMentionNotification(username string, extract string, evt notify.BlockChangeEvent) (string, error) {
|
||||
mentionedUser, err := b.delivery.UserByUsername(username)
|
||||
if err != nil {
|
||||
if b.delivery.IsErrNotFound(err) {
|
||||
if model.IsErrNotFound(err) {
|
||||
// not really an error; could just be someone typed "@sometext"
|
||||
return "", nil
|
||||
} else {
|
||||
@ -186,7 +186,7 @@ func (b *Backend) deliverMentionNotification(username string, extract string, ev
|
||||
}
|
||||
// add mentioned user to board (if not already a member)
|
||||
member, err := b.store.GetMemberForBoard(evt.Board.ID, mentionedUser.Id)
|
||||
if member == nil || b.store.IsErrNotFound(err) {
|
||||
if member == nil || model.IsErrNotFound(err) {
|
||||
// currently all memberships are created as editors by default
|
||||
newBoardMember := &model.BoardMember{
|
||||
UserID: mentionedUser.Id,
|
||||
|
@ -11,6 +11,4 @@ type Store interface {
|
||||
SaveMember(bm *model.BoardMember) (*model.BoardMember, error)
|
||||
|
||||
CreateSubscription(sub *model.Subscription) (*model.Subscription, error)
|
||||
|
||||
IsErrNotFound(err error) bool
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/permissions"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
"github.com/wiggin77/merror"
|
||||
|
||||
@ -83,7 +82,7 @@ func (n *notifier) loop() {
|
||||
for {
|
||||
hint, err := n.store.GetNextNotificationHint(false)
|
||||
switch {
|
||||
case n.store.IsErrNotFound(err):
|
||||
case model.IsErrNotFound(err):
|
||||
// no hints in table; wait up to an hour or when `onNotifyHint` is called again
|
||||
nextNotify = time.Now().Add(time.Hour * 1)
|
||||
n.logger.Debug("notify loop - no hints in queue", mlog.Time("next_check", nextNotify))
|
||||
@ -132,7 +131,7 @@ func (n *notifier) notify() {
|
||||
|
||||
hint, err = n.store.GetNextNotificationHint(true)
|
||||
if err != nil {
|
||||
if store.IsErrNotFound(err) {
|
||||
if model.IsErrNotFound(err) {
|
||||
// Expected when multiple nodes in a cluster try to process the same hint at the same time.
|
||||
// This simply means the other node won. Returning here will simply try fetching another hint.
|
||||
return
|
||||
|
@ -27,6 +27,4 @@ type Store interface {
|
||||
|
||||
UpsertNotificationHint(hint *model.NotificationHint, notificationFreq time.Duration) (*model.NotificationHint, error)
|
||||
GetNextNotificationHint(remove bool) (*model.NotificationHint, error)
|
||||
|
||||
IsErrNotFound(err error) bool
|
||||
}
|
||||
|
@ -29,10 +29,6 @@ type PluginAPI interface {
|
||||
|
||||
// GetChannelMember gets a channel member by userID.
|
||||
GetChannelMember(channelID string, userID string) (*mm_model.ChannelMember, error)
|
||||
|
||||
// IsErrNotFound returns true if `err` or one of its wrapped children are the `ErrNotFound`
|
||||
// as defined in the plugin API.
|
||||
IsErrNotFound(err error) bool
|
||||
}
|
||||
|
||||
// PluginDelivery provides ability to send notifications to direct message channels via Mattermost plugin API.
|
||||
@ -49,9 +45,3 @@ func New(botID string, serverRoot string, api PluginAPI) *PluginDelivery {
|
||||
api: api,
|
||||
}
|
||||
}
|
||||
|
||||
// IsErrNotFound returns true if `err` or one of its wrapped children are the `ErrNotFound`
|
||||
// as defined in the plugin API.
|
||||
func (pd *PluginDelivery) IsErrNotFound(err error) bool {
|
||||
return pd.api.IsErrNotFound(err)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func (pd *PluginDelivery) SubscriptionDeliverSlackAttachments(subscriberID strin
|
||||
// check subscriber is member of channel
|
||||
_, err := pd.api.GetUserByID(subscriberID)
|
||||
if err != nil {
|
||||
if pd.api.IsErrNotFound(err) {
|
||||
if model.IsErrNotFound(err) {
|
||||
// subscriber is not a member of the channel; fail silently.
|
||||
return nil
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ package plugindelivery
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
@ -21,7 +23,7 @@ func (pd *PluginDelivery) UserByUsername(username string) (*mm_model.User, error
|
||||
trimmed := username
|
||||
for ok {
|
||||
user, err = pd.api.GetUserByUsername(trimmed)
|
||||
if err != nil && !isErrNotFound(err) {
|
||||
if err != nil && !model.IsErrNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -51,10 +53,3 @@ func trimUsernameSpecialChar(word string) (string, bool) {
|
||||
|
||||
return word, false
|
||||
}
|
||||
|
||||
// isErrNotFound returns true if the error is a plugin.ErrNotFound. The pluginAPI converts
|
||||
// AppError to the plugin.ErrNotFound var.
|
||||
// TODO: add a `IsErrNotFound` method to the plugin API.
|
||||
func isErrNotFound(err error) bool {
|
||||
return err != nil && err.Error() == "not found"
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
|
||||
mm_model "github.com/mattermost/mattermost-server/v6/model"
|
||||
)
|
||||
|
||||
@ -90,7 +92,7 @@ func newPlugAPIMock(users map[string]*mm_model.User) pluginAPIMock {
|
||||
func (m pluginAPIMock) GetUserByUsername(name string) (*mm_model.User, error) {
|
||||
user, ok := m.users[name]
|
||||
if !ok {
|
||||
return nil, ErrNotFound{}
|
||||
return nil, model.NewErrNotFound(name)
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
@ -109,7 +111,7 @@ func (m pluginAPIMock) GetUserByID(userID string) (*mm_model.User, error) {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrNotFound{}
|
||||
return nil, model.NewErrNotFound(userID)
|
||||
}
|
||||
|
||||
func (m pluginAPIMock) GetTeamMember(teamID string, userID string) (*mm_model.TeamMember, error) {
|
||||
@ -119,7 +121,7 @@ func (m pluginAPIMock) GetTeamMember(teamID string, userID string) (*mm_model.Te
|
||||
}
|
||||
|
||||
if teamID != defTeamID {
|
||||
return nil, ErrNotFound{}
|
||||
return nil, model.NewErrNotFound(teamID)
|
||||
}
|
||||
|
||||
member := &mm_model.TeamMember{
|
||||
@ -130,19 +132,9 @@ func (m pluginAPIMock) GetTeamMember(teamID string, userID string) (*mm_model.Te
|
||||
}
|
||||
|
||||
func (m pluginAPIMock) GetChannelByID(channelID string) (*mm_model.Channel, error) {
|
||||
return nil, ErrNotFound{}
|
||||
return nil, model.NewErrNotFound(channelID)
|
||||
}
|
||||
|
||||
func (m pluginAPIMock) GetChannelMember(channelID string, userID string) (*mm_model.ChannelMember, error) {
|
||||
return nil, ErrNotFound{}
|
||||
}
|
||||
|
||||
func (m pluginAPIMock) IsErrNotFound(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type ErrNotFound struct{}
|
||||
|
||||
func (e ErrNotFound) Error() string {
|
||||
return "not found"
|
||||
return nil, model.NewErrNotFound(userID)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
permissionsMocks "github.com/mattermost/focalboard/server/services/permissions/mocks"
|
||||
|
||||
mmModel "github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -25,12 +26,11 @@ type TestHelper struct {
|
||||
func SetupTestHelper(t *testing.T) *TestHelper {
|
||||
ctrl := gomock.NewController(t)
|
||||
mockStore := permissionsMocks.NewMockStore(ctrl)
|
||||
|
||||
return &TestHelper{
|
||||
t: t,
|
||||
ctrl: ctrl,
|
||||
store: mockStore,
|
||||
permissions: New(mockStore, nil),
|
||||
permissions: New(mockStore, mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,6 @@
|
||||
package localpermissions
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/permissions"
|
||||
|
||||
@ -39,7 +36,7 @@ func (s *Service) HasPermissionToBoard(userID, boardID string, permission *mmMod
|
||||
}
|
||||
|
||||
member, err := s.store.GetMemberForBoard(boardID, userID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -4,9 +4,6 @@
|
||||
package mmpermissions
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/permissions"
|
||||
|
||||
@ -43,7 +40,7 @@ func (s *Service) HasPermissionToBoard(userID, boardID string, permission *mmMod
|
||||
}
|
||||
|
||||
board, err := s.store.GetBoard(boardID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
var boards []*model.Board
|
||||
boards, err = s.store.GetBoardHistory(boardID, model.QueryBoardHistoryOptions{Limit: 1, Descending: true})
|
||||
if err != nil {
|
||||
@ -69,7 +66,7 @@ func (s *Service) HasPermissionToBoard(userID, boardID string, permission *mmMod
|
||||
}
|
||||
|
||||
member, err := s.store.GetMemberForBoard(boardID, userID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
if model.IsErrNotFound(err) {
|
||||
return false
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -80,9 +80,8 @@ type storeMetadata struct {
|
||||
}
|
||||
|
||||
var blacklistedStoreMethodNames = map[string]bool{
|
||||
"Shutdown": true,
|
||||
"IsErrNotFound": true,
|
||||
"DBType": true,
|
||||
"Shutdown": true,
|
||||
"DBType": true,
|
||||
}
|
||||
|
||||
func extractMethodMetadata(method *ast.Field, src []byte) methodData {
|
||||
|
@ -198,7 +198,7 @@ func (s *MattermostAuthLayer) GetTeam(id string) (*model.Team, error) {
|
||||
row := query.QueryRow()
|
||||
var displayName string
|
||||
err := row.Scan(&displayName)
|
||||
if err != nil && !s.IsErrNotFound(err) {
|
||||
if err != nil && !model.IsErrNotFound(err) {
|
||||
s.logger.Error("GetTeam scan error",
|
||||
mlog.String("team_id", id),
|
||||
mlog.Err(err),
|
||||
|
@ -1014,20 +1014,6 @@ func (mr *MockStoreMockRecorder) InsertBoardWithAdmin(arg0, arg1 interface{}) *g
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertBoardWithAdmin", reflect.TypeOf((*MockStore)(nil).InsertBoardWithAdmin), arg0, arg1)
|
||||
}
|
||||
|
||||
// IsErrNotFound mocks base method.
|
||||
func (m *MockStore) IsErrNotFound(arg0 error) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsErrNotFound", arg0)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IsErrNotFound indicates an expected call of IsErrNotFound.
|
||||
func (mr *MockStoreMockRecorder) IsErrNotFound(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsErrNotFound", reflect.TypeOf((*MockStore)(nil).IsErrNotFound), arg0)
|
||||
}
|
||||
|
||||
// PatchBlock mocks base method.
|
||||
func (m *MockStore) PatchBlock(arg0 string, arg1 *model.BlockPatch, arg2 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
@ -632,7 +631,7 @@ func (s *SQLStore) getBoardAndCardByID(db sq.BaseRunner, blockID string) (board
|
||||
}
|
||||
|
||||
if len(blocks) == 0 {
|
||||
return nil, nil, store.NewErrNotFound(blockID)
|
||||
return nil, nil, model.NewErrNotFound(blockID)
|
||||
}
|
||||
|
||||
return s.getBoardAndCard(db, &blocks[0])
|
||||
|
@ -3,7 +3,6 @@ package sqlstore
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@ -292,7 +291,7 @@ func (s *SQLStore) insertBoard(db sq.BaseRunner, board *model.Board, userID stri
|
||||
}
|
||||
|
||||
existingBoard, err := s.getBoard(db, board.ID)
|
||||
if err != nil && !s.IsErrNotFound(err) {
|
||||
if err != nil && !model.IsErrNotFound(err) {
|
||||
return nil, fmt.Errorf("insertBoard error occurred while fetching existing board %s: %w", board.ID, err)
|
||||
}
|
||||
|
||||
@ -466,7 +465,7 @@ func (s *SQLStore) saveMember(db sq.BaseRunner, bm *model.BoardMember) (*model.B
|
||||
}
|
||||
|
||||
oldMember, err := s.getMemberForBoard(db, bm.BoardID, bm.UserID)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
if err != nil && !model.IsErrNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
@ -30,7 +29,7 @@ func (s *SQLStore) getCategory(db sq.BaseRunner, id string) (*model.Category, er
|
||||
}
|
||||
|
||||
if len(categories) == 0 {
|
||||
return nil, store.NewErrNotFound(id)
|
||||
return nil, model.NewErrNotFound(id)
|
||||
}
|
||||
|
||||
return &categories[0], nil
|
||||
|
@ -557,7 +557,7 @@ func (s *SQLStore) getDMBoards(tx sq.BaseRunner) ([]*model.Board, error) {
|
||||
}
|
||||
|
||||
boards, err := s.getBoardsByCondition(tx, conditions)
|
||||
if err != nil && errors.Is(err, sql.ErrNoRows) {
|
||||
if err != nil && model.IsErrNotFound(err) {
|
||||
return []*model.Board{}, nil
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
@ -103,7 +102,7 @@ func (s *SQLStore) deleteNotificationHint(db sq.BaseRunner, blockID string) erro
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
return store.NewErrNotFound(blockID)
|
||||
return model.NewErrNotFound(blockID)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -135,7 +134,7 @@ func (s *SQLStore) getNotificationHint(db sq.BaseRunner, blockID string) (*model
|
||||
return nil, err
|
||||
}
|
||||
if len(hint) == 0 {
|
||||
return nil, store.NewErrNotFound(blockID)
|
||||
return nil, model.NewErrNotFound(blockID)
|
||||
}
|
||||
return hint[0], nil
|
||||
}
|
||||
@ -166,7 +165,7 @@ func (s *SQLStore) getNextNotificationHint(db sq.BaseRunner, remove bool) (*mode
|
||||
return nil, err
|
||||
}
|
||||
if len(hints) == 0 {
|
||||
return nil, store.NewErrNotFound("")
|
||||
return nil, model.NewErrNotFound("")
|
||||
}
|
||||
|
||||
hint := hints[0]
|
||||
@ -187,7 +186,7 @@ func (s *SQLStore) getNextNotificationHint(db sq.BaseRunner, remove bool) (*mode
|
||||
if rows == 0 {
|
||||
// another node likely has grabbed this hint for processing concurrently; let that node handle it
|
||||
// and we'll return an error here so we try again.
|
||||
return nil, store.NewErrNotFound(hint.BlockID)
|
||||
return nil, model.NewErrNotFound(hint.BlockID)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
)
|
||||
@ -114,7 +113,7 @@ func (s *SQLStore) deleteSubscription(db sq.BaseRunner, blockID string, subscrib
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
return store.NewErrNotFound(blockID + "," + subscriberID)
|
||||
return model.NewErrNotFound(blockID + "," + subscriberID)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -150,7 +149,7 @@ func (s *SQLStore) getSubscription(db sq.BaseRunner, blockID string, subscriberI
|
||||
return nil, err
|
||||
}
|
||||
if len(subscriptions) == 0 {
|
||||
return nil, store.NewErrNotFound(blockID + "," + subscriberID)
|
||||
return nil, model.NewErrNotFound(blockID + "," + subscriberID)
|
||||
}
|
||||
return subscriptions[0], nil
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
)
|
||||
@ -17,7 +14,7 @@ func (s *SQLStore) getSystemSetting(db sq.BaseRunner, key string) (string, error
|
||||
|
||||
var result string
|
||||
err := scanner.Scan(&result)
|
||||
if err != nil && !errors.Is(sql.ErrNoRows, err) {
|
||||
if err != nil && !model.IsErrNotFound(err) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
"github.com/mattermost/focalboard/server/utils"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
@ -21,7 +20,7 @@ func (s *SQLStore) CloseRows(rows *sql.Rows) {
|
||||
}
|
||||
|
||||
func (s *SQLStore) IsErrNotFound(err error) bool {
|
||||
return store.IsErrNotFound(err)
|
||||
return model.IsErrNotFound(err)
|
||||
}
|
||||
|
||||
func PrepareNewTestDatabase() (dbType string, connectionString string, err error) {
|
||||
|
@ -3,9 +3,6 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
@ -136,42 +133,5 @@ type Store interface {
|
||||
|
||||
DBType() string
|
||||
|
||||
IsErrNotFound(err error) bool
|
||||
|
||||
GetLicense() *mmModel.License
|
||||
}
|
||||
|
||||
// ErrNotFound is an error type that can be returned by store APIs when a query unexpectedly fetches no records.
|
||||
type ErrNotFound struct {
|
||||
resource string
|
||||
}
|
||||
|
||||
// NewErrNotFound creates a new ErrNotFound instance.
|
||||
func NewErrNotFound(resource string) *ErrNotFound {
|
||||
return &ErrNotFound{
|
||||
resource: resource,
|
||||
}
|
||||
}
|
||||
|
||||
func (nf *ErrNotFound) Error() string {
|
||||
return fmt.Sprintf("{%s} not found", nf.resource)
|
||||
}
|
||||
|
||||
// IsErrNotFound returns true if `err` is or wraps a ErrNotFound.
|
||||
func IsErrNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// check if this is a store.ErrNotFound
|
||||
var nf *ErrNotFound
|
||||
if errors.As(err, &nf) {
|
||||
return true
|
||||
}
|
||||
|
||||
// check if this is a sql.ErrNotFound
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package storetests
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -106,7 +105,7 @@ func testGetBoard(t *testing.T, store store.Store) {
|
||||
|
||||
t.Run("nonexisting board", func(t *testing.T) {
|
||||
rBoard, err := store.GetBoard("nonexistent-id")
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
require.Nil(t, rBoard)
|
||||
})
|
||||
}
|
||||
@ -237,7 +236,7 @@ func testInsertBoard(t *testing.T, store store.Store) {
|
||||
require.Error(t, err)
|
||||
|
||||
rBoard, err := store.GetBoard(board.ID)
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
require.Nil(t, rBoard)
|
||||
})
|
||||
|
||||
@ -479,7 +478,7 @@ func testDeleteBoard(t *testing.T, store store.Store) {
|
||||
require.NoError(t, store.DeleteBoard(boardID, userID))
|
||||
|
||||
r2Board, err := store.GetBoard(boardID)
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
require.Nil(t, r2Board)
|
||||
})
|
||||
}
|
||||
@ -569,7 +568,7 @@ func testGetMemberForBoard(t *testing.T, store store.Store) {
|
||||
|
||||
t.Run("should return a no rows error for nonexisting membership", func(t *testing.T) {
|
||||
bm, err := store.GetMemberForBoard(boardID, userID)
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
require.Nil(t, bm)
|
||||
})
|
||||
|
||||
@ -674,7 +673,7 @@ func testDeleteMember(t *testing.T, store store.Store) {
|
||||
require.NoError(t, store.DeleteMember(boardID, userID))
|
||||
|
||||
rbm, err := store.GetMemberForBoard(boardID, userID)
|
||||
require.ErrorIs(t, err, sql.ErrNoRows)
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
require.Nil(t, rbm)
|
||||
|
||||
memberHistory, err = store.GetBoardMemberHistory(boardID, userID, 0)
|
||||
|
@ -124,13 +124,13 @@ func testDeleteNotificationHint(t *testing.T, store store.Store) {
|
||||
|
||||
// check the notification hint was deleted
|
||||
hint, err = store.GetNotificationHint(hintNew.BlockID)
|
||||
require.True(t, store.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
require.True(t, model.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
assert.Nil(t, hint)
|
||||
})
|
||||
|
||||
t.Run("delete non-existent notification hint", func(t *testing.T) {
|
||||
err := store.DeleteNotificationHint("bogus")
|
||||
require.True(t, store.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
require.True(t, model.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
})
|
||||
}
|
||||
|
||||
@ -152,7 +152,7 @@ func testGetNotificationHint(t *testing.T, store store.Store) {
|
||||
|
||||
t.Run("get non-existent notification hint", func(t *testing.T) {
|
||||
hint, err := store.GetNotificationHint("bogus")
|
||||
require.True(t, store.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
require.True(t, model.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
assert.Nil(t, hint, "hint should be nil")
|
||||
})
|
||||
}
|
||||
@ -199,7 +199,7 @@ func testGetNextNotificationHint(t *testing.T, store store.Store) {
|
||||
|
||||
for {
|
||||
hint, err2 := store.GetNextNotificationHint(false)
|
||||
if store.IsErrNotFound(err2) {
|
||||
if model.IsErrNotFound(err2) {
|
||||
break
|
||||
}
|
||||
require.NoError(t, err2, "get next notification hint should not error")
|
||||
@ -209,7 +209,7 @@ func testGetNextNotificationHint(t *testing.T, store store.Store) {
|
||||
}
|
||||
|
||||
_, err = store.GetNextNotificationHint(false)
|
||||
require.True(t, store.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
require.True(t, model.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
})
|
||||
|
||||
t.Run("get next notification hint and remove", func(t *testing.T) {
|
||||
@ -232,14 +232,14 @@ func testGetNextNotificationHint(t *testing.T, store store.Store) {
|
||||
|
||||
// should be no hint left
|
||||
_, err = store.GetNextNotificationHint(false)
|
||||
require.True(t, store.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
require.True(t, model.IsErrNotFound(err), "error should be of type store.ErrNotFound")
|
||||
})
|
||||
}
|
||||
|
||||
func emptyNotificationHintTable(store store.Store) error {
|
||||
for {
|
||||
hint, err := store.GetNextNotificationHint(false)
|
||||
if store.IsErrNotFound(err) {
|
||||
if model.IsErrNotFound(err) {
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -172,9 +172,7 @@ func testDeleteSubscription(t *testing.T, s store.Store) {
|
||||
t.Run("delete non-existent subscription", func(t *testing.T) {
|
||||
err := s.DeleteSubscription("bogus", "bogus")
|
||||
require.Error(t, err, "delete non-existent subscription should error")
|
||||
var nf *store.ErrNotFound
|
||||
require.ErrorAs(t, err, &nf, "error should be of type store.ErrNotFound")
|
||||
require.True(t, store.IsErrNotFound(err))
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
})
|
||||
}
|
||||
|
||||
@ -243,9 +241,7 @@ func testGetSubscription(t *testing.T, s store.Store) {
|
||||
t.Run("get non-existent subscription", func(t *testing.T) {
|
||||
sub, err := s.GetSubscription("bogus", "bogus")
|
||||
require.Error(t, err, "get non-existent subscription should error")
|
||||
var nf *store.ErrNotFound
|
||||
require.ErrorAs(t, err, &nf, "error should be of type store.ErrNotFound")
|
||||
require.True(t, store.IsErrNotFound(err))
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
require.Nil(t, sub, "get subscription should return nil")
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
package storetests
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -50,7 +49,7 @@ func testGetTeamUsers(t *testing.T, store store.Store) {
|
||||
t.Run("GetTeamUSers", func(t *testing.T) {
|
||||
users, err := store.GetUsersByTeam("team_1")
|
||||
require.Equal(t, 0, len(users))
|
||||
require.Equal(t, sql.ErrNoRows, err)
|
||||
require.True(t, model.IsErrNotFound(err), "Should be ErrNotFound compatible error")
|
||||
|
||||
userID := utils.NewID(utils.IDTypeUser)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user