diff --git a/models/action.go b/models/action.go index 7684719..f981532 100644 --- a/models/action.go +++ b/models/action.go @@ -23,5 +23,6 @@ func (m *Model) Actions() ([]*Action, error) { // Action returns a single action from its ID func (m *Model) Action(id int) (*Action, error) { - return m.SelectActionByID(id) + act, err := m.SelectActionByID(id) + return act, wrapNotFound(err) } diff --git a/models/err_model_test.go b/models/err_model_test.go new file mode 100644 index 0000000..486a965 --- /dev/null +++ b/models/err_model_test.go @@ -0,0 +1,42 @@ +package models_test + +import ( + "gitea.deepak.science/deepak/gogmagog/models" +) + +func (e *errorStore) SelectActions() ([]*models.Action, error) { + return nil, e.error +} + +func (e *errorStore) SelectActionByID(id int) (*models.Action, error) { + return nil, e.error +} + +func (e *errorStore) SelectPlans() ([]*models.Plan, error) { + return nil, e.error +} + +func (e *errorStore) SelectPlanByID(id int) (*models.Plan, error) { + return nil, e.error +} + +func (e *errorStore) InsertPlan(plan *models.Plan) (int, error) { + return 0, e.error +} + +func (e *errorStore) SelectActionsByPlanID(plan *models.Plan) ([]*models.Action, error) { + return nil, e.error +} + +func (e *errorStore) ConnectionLive() error { + return e.error +} + +type errorStore struct { + error error +} + +func getErrorModel(err error) *models.Model { + e := &errorStore{error: err} + return models.New(e) +} diff --git a/models/errors.go b/models/errors.go new file mode 100644 index 0000000..8274dc4 --- /dev/null +++ b/models/errors.go @@ -0,0 +1,29 @@ +package models + +import ( + "database/sql" +) + +type notFoundError struct { + error +} + +func (e *notFoundError) NotFound() bool { + return true +} + +// IsNotFoundError returns true if the model deems it a not found error. +func IsNotFoundError(err error) bool { + type notFound interface { + NotFound() bool + } + te, ok := err.(notFound) + return ok && te.NotFound() +} + +func wrapNotFound(err error) error { + if err == sql.ErrNoRows { + return ¬FoundError{error: err} + } + return err +} diff --git a/models/errors_test.go b/models/errors_test.go new file mode 100644 index 0000000..88baab0 --- /dev/null +++ b/models/errors_test.go @@ -0,0 +1,42 @@ +package models_test + +import ( + "database/sql" + "fmt" + "gitea.deepak.science/deepak/gogmagog/models" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestRandomErrNotNotFound(t *testing.T) { + assert := assert.New(t) + + err := fmt.Errorf("example") + + assert.False(models.IsNotFoundError(err)) +} + +type MyError struct { + error +} + +func (e *MyError) NotFound() bool { + return true +} + +func TestCustomInterface(t *testing.T) { + assert := assert.New(t) + + err := &MyError{fmt.Errorf("example")} + + assert.True(models.IsNotFoundError(err)) +} +func TestErrorModelWrapping(t *testing.T) { + assert := assert.New(t) + m := getErrorModel(sql.ErrNoRows) + + _, err := m.Plan(0) + assert.True(models.IsNotFoundError(err)) + _, err = m.Action(0) + assert.True(models.IsNotFoundError(err)) +} diff --git a/models/plan.go b/models/plan.go index 001dd3d..9244130 100644 --- a/models/plan.go +++ b/models/plan.go @@ -17,7 +17,8 @@ func (m *Model) Plans() ([]*Plan, error) { // Plan returns a single plan from the store by plan_id. func (m *Model) Plan(id int) (*Plan, error) { - return m.SelectPlanByID(id) + plan, err := m.SelectPlanByID(id) + return plan, wrapNotFound(err) } // AddPlan inserts a given plan into the store, returning the generated PlanID. The provided PlanID is ignored.