You've already forked focalboard
							
							
				mirror of
				https://github.com/mattermost/focalboard.git
				synced 2025-10-31 00:17:42 +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:
		| @@ -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) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user