ICU-738/Refactor internal/db to domain errors (#815)

* Refactor internal/db to domain errors
pull/843/head
Louis Ruch 5 years ago committed by GitHub
parent b5d84495a3
commit bfbb179741
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,17 @@
Canonical reference for changes, improvements, and bugfixes for Boundary.
## vNext
### Changes/Deprecations
### New and Improved
* controller: Improved error handling in db
([PR](https://github.com/hashicorp/boundary/pull/815))
### Bug Fixes
## 0.1.3
### Changes/Deprecations

@ -1,21 +1,22 @@
package password
import "errors"
import "github.com/hashicorp/boundary/internal/errors"
// TODO: remove these errors once all code has been refactored to creating inline domain errors
var (
// ErrTooShort results from attempting to set a password which is to
// short.
ErrTooShort = errors.New("too short")
ErrTooShort = errors.E(errors.WithCode(errors.PasswordTooShort))
// ErrUnsupportedConfiguration results from attempting to perform an
// operation that sets a password configuration to an unsupported type.
ErrUnsupportedConfiguration = errors.New("unsupported configuration")
ErrUnsupportedConfiguration = errors.E(errors.WithCode(errors.PasswordUnsupportedConfiguration))
// ErrInvalidConfiguration results from attempting to perform an
// operation that sets a password configuration with invalid settings.
ErrInvalidConfiguration = errors.New("invalid configuration")
ErrInvalidConfiguration = errors.E(errors.WithCode(errors.PasswordInvalidConfiguration))
// ErrPasswordsEqual is returned from ChangePassword when the old and
// new passwords are equal.
ErrPasswordsEqual = errors.New("old and new password are equal")
ErrPasswordsEqual = errors.E(errors.WithCode(errors.PasswordsEqual))
)

@ -123,7 +123,7 @@ func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt
a := allocAccount()
a.PublicId = withPublicId
if err := r.reader.LookupByPublicId(ctx, a); err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("lookup: password account: failed %w for %s", err, withPublicId)

@ -626,7 +626,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
masks []string
want *Account
wantCount int
wantIsErr error
wantIsErr errors.Code
}{
{
name: "nil-Account",
@ -635,7 +635,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: makeNil(),
masks: []string{"Name", "Description"},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "nil-embedded-Account",
@ -644,7 +644,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: makeEmbeddedNil(),
masks: []string{"Name", "Description"},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "no-public-id",
@ -653,7 +653,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: deletePublicId(),
masks: []string{"Name", "Description"},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "updating-non-existent-Account",
@ -664,7 +664,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: combine(nonExistentPublicId(), changeName("test-update-name-repo")),
masks: []string{"Name"},
wantIsErr: errors.ErrRecordNotFound,
wantIsErr: errors.RecordNotFound,
},
{
name: "empty-field-mask",
@ -674,7 +674,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
},
chgFn: changeName("test-update-name-repo"),
wantIsErr: errors.ErrEmptyFieldMask,
wantIsErr: errors.EmptyFieldMask,
},
{
name: "read-only-fields-in-field-mask",
@ -685,7 +685,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: changeName("test-update-name-repo"),
masks: []string{"PublicId", "CreateTime", "UpdateTime", "AuthMethodId"},
wantIsErr: errors.ErrInvalidFieldMask,
wantIsErr: errors.InvalidFieldMask,
},
{
name: "unknown-field-in-field-mask",
@ -696,7 +696,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: changeName("test-update-name-repo"),
masks: []string{"Bilbo"},
wantIsErr: errors.ErrInvalidFieldMask,
wantIsErr: errors.InvalidFieldMask,
},
{
name: "change-name",
@ -843,7 +843,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: changeLoginName("KaZmIeRcZaK"),
masks: []string{"LoginName"},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "change-login-name-to-short",
@ -854,7 +854,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: changeLoginName("ka"),
masks: []string{"LoginName"},
wantIsErr: ErrTooShort,
wantIsErr: errors.PasswordTooShort,
},
{
name: "delete-login-name",
@ -865,7 +865,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
},
chgFn: changeLoginName(""),
masks: []string{"LoginName"},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
}
@ -892,8 +892,8 @@ func TestRepository_UpdateAccount(t *testing.T) {
orig = tt.chgFn(orig)
}
got, gotCount, err := repo.UpdateAccount(context.Background(), org.GetPublicId(), orig, 1, tt.masks)
if tt.wantIsErr != nil {
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
if tt.wantIsErr != 0 {
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
assert.Equal(tt.wantCount, gotCount, "row count")
assert.Nil(got)
return
@ -956,7 +956,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
assert.Equal(db.NoRowsAffected, gotCount2, "row count")
err = db.TestVerifyOplog(t, rw, ab.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
t.Run("valid-duplicate-names-diff-AuthMethods", func(t *testing.T) {
@ -1034,7 +1034,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
assert.Equal(db.NoRowsAffected, gotCount2, "row count")
err = db.TestVerifyOplog(t, rw, ab.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
t.Run("valid-duplicate-loginnames-diff-AuthMethods", func(t *testing.T) {

@ -104,7 +104,7 @@ func (r *Repository) LookupAuthMethod(ctx context.Context, publicId string, opt
a := allocAuthMethod()
a.PublicId = publicId
if err := r.reader.LookupByPublicId(ctx, &a); err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("lookup: password auth method: failed %w for %s", err, publicId)

@ -90,7 +90,7 @@ func (r *Repository) setArgon2Conf(ctx context.Context, scopeId string, c *Argon
func(rr db.Reader, w db.Writer) error {
where, args := c.whereDup()
if err := rr.LookupWhere(ctx, newArgon2Conf, where, args...); err != nil {
if err != errors.ErrRecordNotFound {
if !errors.IsNotFoundError(err) {
return err
}
newArgon2Conf = c.clone()

@ -140,17 +140,17 @@ func TestRepository_GetConfiguration(t *testing.T) {
name string
authMethodId string
want *Argon2Configuration
wantIsErr error
wantIsErr errors.Code
}{
{
name: "invalid-no-authMethodId",
authMethodId: "",
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "invalid-authMethodId",
authMethodId: "abcdefghijk",
wantIsErr: errors.ErrRecordNotFound,
wantIsErr: errors.RecordNotFound,
},
{
name: "valid-authMethodId",
@ -163,8 +163,8 @@ func TestRepository_GetConfiguration(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := repo.GetConfiguration(ctx, tt.authMethodId)
if tt.wantIsErr != nil {
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
if tt.wantIsErr != 0 {
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
assert.Nil(got, "returned configuration")
return
}
@ -212,26 +212,26 @@ func TestRepository_SetConfiguration(t *testing.T) {
in Configuration
want *Argon2Configuration
wantUnknownErr bool
wantIsErr error
wantIsErr errors.Code
}{
{
name: "invalid-nil-config",
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "nil-embedded-config",
in: &Argon2Configuration{},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "invalid-no-authMethodId",
in: NewArgon2Configuration(),
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "unknown-configuration-type",
in: tconf(0),
wantIsErr: ErrUnsupportedConfiguration,
wantIsErr: errors.PasswordUnsupportedConfiguration,
},
{
name: "invalid-unknown-authMethodId",
@ -259,7 +259,7 @@ func TestRepository_SetConfiguration(t *testing.T) {
KeyLength: 32,
},
},
wantIsErr: ErrInvalidConfiguration,
wantIsErr: errors.PasswordInvalidConfiguration,
},
{
name: "valid",
@ -290,8 +290,8 @@ func TestRepository_SetConfiguration(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := repo.SetConfiguration(context.Background(), o.GetPublicId(), tt.in)
if tt.wantIsErr != nil {
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
if tt.wantIsErr != 0 {
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
assert.Nil(got, "returned configuration")
return
}

@ -306,7 +306,7 @@ func (r *Repository) SetPassword(ctx context.Context, scopeId, accountId, passwo
oldCred := allocCredential()
if err := rr.LookupWhere(ctx, &oldCred, "password_account_id = ?", accountId); err != nil {
if !errors.Is(err, errors.ErrRecordNotFound) {
if !errors.IsNotFoundError(err) {
return err
}
}

@ -119,7 +119,7 @@ func TestRepository_Authenticate(t *testing.T) {
assert.Equal(tt.args.loginName, authAcct.LoginName, "LoginName")
err = db.TestVerifyOplog(t, rw, authAcct.CredentialId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -276,7 +276,7 @@ func TestRepository_ChangePassword(t *testing.T) {
name string
args args
wantAccount bool
wantIsErr error
wantIsErr errors.Code
}{
{
name: "invalid-no-accountId",
@ -285,7 +285,7 @@ func TestRepository_ChangePassword(t *testing.T) {
old: passwd,
new: "12345678-changed",
},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "invalid-no-current-password",
@ -294,7 +294,7 @@ func TestRepository_ChangePassword(t *testing.T) {
old: "",
new: "12345678-changed",
},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "invalid-no-new-password",
@ -303,7 +303,7 @@ func TestRepository_ChangePassword(t *testing.T) {
old: passwd,
new: "",
},
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "invalid-same-passwords",
@ -312,7 +312,7 @@ func TestRepository_ChangePassword(t *testing.T) {
old: passwd,
new: passwd,
},
wantIsErr: ErrPasswordsEqual,
wantIsErr: errors.PasswordsEqual,
},
{
name: "auth-failure-unknown-accountId",
@ -322,7 +322,7 @@ func TestRepository_ChangePassword(t *testing.T) {
new: "12345678-changed",
},
wantAccount: false,
wantIsErr: errors.ErrRecordNotFound,
wantIsErr: errors.RecordNotFound,
},
{
name: "auth-failure-wrong-current-password",
@ -332,7 +332,6 @@ func TestRepository_ChangePassword(t *testing.T) {
new: "12345678-changed",
},
wantAccount: false,
wantIsErr: nil,
},
{
name: "password-to-short",
@ -341,7 +340,7 @@ func TestRepository_ChangePassword(t *testing.T) {
old: passwd,
new: "1",
},
wantIsErr: ErrTooShort,
wantIsErr: errors.PasswordTooShort,
},
{
name: "valid",
@ -369,9 +368,9 @@ func TestRepository_ChangePassword(t *testing.T) {
authAcct1 := authFn(passwd, "original account")
chgAuthAcct, err := repo.ChangePassword(context.Background(), o.GetPublicId(), tt.args.acctId, tt.args.old, tt.args.new, authAcct1.Version)
if tt.wantIsErr != nil {
if tt.wantIsErr != 0 {
assert.Error(err)
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
assert.Nil(chgAuthAcct, "returned account")
authAcct2 := authFn(passwd, "error changing password: using old password")
assert.Equal(authAcct1.CredentialId, authAcct2.CredentialId, "CredentialId should not change")

@ -146,7 +146,7 @@ func (r *Repository) LookupAuthToken(ctx context.Context, id string, opt ...Opti
at := allocAuthToken()
at.PublicId = id
if err := r.reader.LookupByPublicId(ctx, at); err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("auth token: lookup: %w", err)
@ -184,7 +184,7 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
retAT, err := r.LookupAuthToken(ctx, id, withTokenValue())
if err != nil {
retAT = nil
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("validate token: %w", err)
@ -295,7 +295,7 @@ func (r *Repository) DeleteAuthToken(ctx context.Context, id string, opt ...Opti
at, err := r.LookupAuthToken(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return db.NoRowsAffected, nil
}
return db.NoRowsAffected, fmt.Errorf("delete: auth token: lookup %w", err)

@ -3,8 +3,7 @@ package dbassert
import (
"database/sql"
dbassert "github.com/hashicorp/dbassert"
"github.com/hashicorp/dbassert"
gormAssert "github.com/hashicorp/dbassert/gorm"
"github.com/stretchr/testify/assert"
)

@ -4,26 +4,22 @@
package common
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/hashicorp/boundary/internal/errors"
"github.com/jinzhu/gorm"
)
var (
// ErrInvalidParameter is returned when a required parameter is nil.
ErrInvalidParameter = errors.New("nil parameter")
)
// UpdateFields will create a map[string]interface of the update values to be
// sent to the db. The map keys will be the field names for the fields to be
// updated. The caller provided fieldMaskPaths and setToNullPaths must not
// intersect. fieldMaskPaths and setToNullPaths cannot both be zero len.
func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []string) (map[string]interface{}, error) {
const op = "common.UpdateFields"
if i == nil {
return nil, fmt.Errorf("interface is missing: %w", ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "interface is missing")
}
if fieldMaskPaths == nil {
fieldMaskPaths = []string{}
@ -32,7 +28,7 @@ func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []strin
setToNullPaths = []string{}
}
if len(fieldMaskPaths) == 0 && len(setToNullPaths) == 0 {
return nil, errors.New("both fieldMaskPaths and setToNullPaths are zero len")
return nil, errors.New(errors.InvalidParameter, op, "both fieldMaskPaths and setToNullPaths are zero len")
}
inter, maskPaths, nullPaths, err := Intersection(fieldMaskPaths, setToNullPaths)
@ -40,7 +36,7 @@ func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []strin
return nil, err
}
if len(inter) != 0 {
return nil, fmt.Errorf("fieldMashPaths and setToNullPaths cannot intersect")
return nil, errors.New(errors.InvalidParameter, op, "fieldMashPaths and setToNullPaths cannot intersect")
}
updateFields := map[string]interface{}{} // case sensitive update fields to values
@ -91,11 +87,11 @@ func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []strin
}
if missing := findMissingPaths(setToNullPaths, found); len(missing) != 0 {
return nil, fmt.Errorf("null paths not found in resource: %s", missing)
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("null paths not found in resource: %s", missing))
}
if missing := findMissingPaths(fieldMaskPaths, found); len(missing) != 0 {
return nil, fmt.Errorf("field mask paths not found in resource: %s", missing)
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("field mask paths not found in resource: %s", missing))
}
return updateFields, nil
@ -116,11 +112,12 @@ func findMissingPaths(paths []string, foundPaths map[string]struct{}) []string {
// of the original av and bv, with the key set to uppercase and value set to the
// original
func Intersection(av, bv []string) ([]string, map[string]string, map[string]string, error) {
const op = "common.Intersection"
if av == nil {
return nil, nil, nil, fmt.Errorf("av is missing: %w", ErrInvalidParameter)
return nil, nil, nil, errors.New(errors.InvalidParameter, op, "av is missing")
}
if bv == nil {
return nil, nil, nil, fmt.Errorf("bv is missing: %w", ErrInvalidParameter)
return nil, nil, nil, errors.New(errors.InvalidParameter, op, "bv is missing")
}
if len(av) == 0 && len(bv) == 0 {
return []string{}, map[string]string{}, map[string]string{}, nil

@ -147,7 +147,7 @@ func Test_intersection(t *testing.T) {
want1: nil,
want2: nil,
wantErr: true,
wantErrMsg: "av is missing: nil parameter",
wantErrMsg: "common.Intersection: av is missing: parameter violation: error #100",
},
{
name: "nil-bv",
@ -159,7 +159,7 @@ func Test_intersection(t *testing.T) {
want1: nil,
want2: nil,
wantErr: true,
wantErrMsg: "bv is missing: nil parameter",
wantErrMsg: "common.Intersection: bv is missing: parameter violation: error #100",
},
}
for _, tt := range tests {
@ -206,7 +206,7 @@ func TestUpdateFields(t *testing.T) {
},
want: nil,
wantErr: true,
wantErrMsg: "interface is missing: nil parameter",
wantErrMsg: "common.UpdateFields: interface is missing: parameter violation: error #100",
},
{
name: "missing fieldmasks",
@ -217,7 +217,7 @@ func TestUpdateFields(t *testing.T) {
},
want: nil,
wantErr: true,
wantErrMsg: "both fieldMaskPaths and setToNullPaths are zero len",
wantErrMsg: "common.UpdateFields: both fieldMaskPaths and setToNullPaths are zero len: parameter violation: error #100",
},
{
name: "missing null fields",
@ -239,7 +239,7 @@ func TestUpdateFields(t *testing.T) {
setToNullPaths: nil,
},
wantErr: true,
wantErrMsg: "both fieldMaskPaths and setToNullPaths are zero len",
wantErrMsg: "common.UpdateFields: both fieldMaskPaths and setToNullPaths are zero len: parameter violation: error #100",
},
{
name: "not found masks",
@ -250,7 +250,7 @@ func TestUpdateFields(t *testing.T) {
},
want: nil,
wantErr: true,
wantErrMsg: "field mask paths not found in resource: [invalidFieldName]",
wantErrMsg: "common.UpdateFields: field mask paths not found in resource: [invalidFieldName]: parameter violation: error #100",
},
{
name: "not found null paths",
@ -261,7 +261,7 @@ func TestUpdateFields(t *testing.T) {
},
want: nil,
wantErr: true,
wantErrMsg: "null paths not found in resource: [invalidFieldName]",
wantErrMsg: "common.UpdateFields: null paths not found in resource: [invalidFieldName]: parameter violation: error #100",
},
{
name: "intersection",
@ -272,7 +272,7 @@ func TestUpdateFields(t *testing.T) {
},
want: nil,
wantErr: true,
wantErrMsg: "fieldMashPaths and setToNullPaths cannot intersect",
wantErrMsg: "common.UpdateFields: fieldMashPaths and setToNullPaths cannot intersect: parameter violation: error #100",
},
{
name: "valid",
@ -381,7 +381,7 @@ func TestUpdateFields(t *testing.T) {
},
want: nil,
wantErr: true,
wantErrMsg: "null paths not found in resource: [invalidFieldName]",
wantErrMsg: "common.UpdateFields: null paths not found in resource: [invalidFieldName]: parameter violation: error #100",
},
}
for _, tt := range tests {

@ -3,7 +3,6 @@ package db
import (
"context"
"database/sql"
stderrors "errors"
"fmt"
"reflect"
"strings"
@ -180,13 +179,14 @@ func New(underlying *gorm.DB) *Db {
// Exec will execute the sql with the values as parameters. The int returned
// is the number of rows affected by the sql. No options are currently
// supported.
func (rw *Db) Exec(ctx context.Context, sql string, values []interface{}, opt ...Option) (int, error) {
func (rw *Db) Exec(_ context.Context, sql string, values []interface{}, _ ...Option) (int, error) {
const op = "db.Exec"
if sql == "" {
return NoRowsAffected, fmt.Errorf("missing sql: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing sql")
}
gormDb := rw.underlying.Exec(sql, values...)
if gormDb.Error != nil {
return NoRowsAffected, fmt.Errorf("exec: failed: %w", gormDb.Error)
return NoRowsAffected, errors.Wrap(gormDb.Error, op)
}
return int(gormDb.RowsAffected), nil
}
@ -195,29 +195,32 @@ func (rw *Db) Exec(ctx context.Context, sql string, values []interface{}, opt ..
// operate within the context of any ongoing transaction for the db.Reader. The
// caller must close the returned *sql.Rows. Query can/should be used in
// combination with ScanRows.
func (rw *Db) Query(ctx context.Context, sql string, values []interface{}, opt ...Option) (*sql.Rows, error) {
func (rw *Db) Query(_ context.Context, sql string, values []interface{}, _ ...Option) (*sql.Rows, error) {
const op = "db.Query"
if sql == "" {
return nil, fmt.Errorf("raw missing sql: %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "missing sql")
}
gormDb := rw.underlying.Raw(sql, values...)
if gormDb.Error != nil {
return nil, fmt.Errorf("exec: failed: %w", gormDb.Error)
return nil, errors.Wrap(gormDb.Error, op)
}
return gormDb.Rows()
}
// Scan rows will scan the rows into the interface
func (rw *Db) ScanRows(rows *sql.Rows, result interface{}) error {
const op = "db.ScanRows"
if rw.underlying == nil {
return fmt.Errorf("scan rows: missing underlying db %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(result) {
return fmt.Errorf("scan rows: result is missing %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing result")
}
return rw.underlying.ScanRows(rows, result)
}
func (rw *Db) lookupAfterWrite(ctx context.Context, i interface{}, opt ...Option) error {
const op = "db.lookupAfterWrite"
opts := GetOpts(opt...)
withLookup := opts.withLookup
@ -225,7 +228,7 @@ func (rw *Db) lookupAfterWrite(ctx context.Context, i interface{}, opt ...Option
return nil
}
if err := rw.LookupById(ctx, i, opt...); err != nil {
return fmt.Errorf("lookup after write: %w", err)
return errors.Wrap(err, op)
}
return nil
}
@ -235,22 +238,23 @@ func (rw *Db) lookupAfterWrite(ctx context.Context, i interface{}, opt ...Option
// NewOplogMsg will return in-memory oplog message. WithOplog and NewOplogMsg
// cannot be used together. WithLookup with to force a lookup after create.
func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
const op = "db.Create"
if rw.underlying == nil {
return fmt.Errorf("create: missing underlying db: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return fmt.Errorf("create: interface is missing: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing interface")
}
opts := GetOpts(opt...)
withOplog := opts.withOplog
if withOplog && opts.newOplogMsg != nil {
return fmt.Errorf("create: both WithOplog and NewOplogMsg options have been specified: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
}
if withOplog {
// let's validate oplog options before we start writing to the database
_, err := validateOplogArgs(i, opts)
if err != nil {
return fmt.Errorf("create: oplog validation failed: %w", err)
return errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
}
}
// these fields should be nil, since they are not writeable and we want the
@ -260,7 +264,7 @@ func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
if !opts.withSkipVetForWrite {
if vetter, ok := i.(VetForWriter); ok {
if err := vetter.VetForWrite(ctx, rw, CreateOp); err != nil {
return fmt.Errorf("create: vet for write failed: %w", err)
return errors.Wrap(err, op, errors.WithMsg("vet for write failed"))
}
}
}
@ -269,26 +273,26 @@ func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
var err error
ticket, err = rw.GetTicket(i)
if err != nil {
return fmt.Errorf("create: unable to get ticket: %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
}
}
if err := rw.underlying.Create(i).Error; err != nil {
return fmt.Errorf("create: failed: %w", err)
return errors.Wrap(err, op, errors.WithMsg("create failed"))
}
if withOplog {
if err := rw.addOplog(ctx, CreateOp, opts, ticket, i); err != nil {
return err
return errors.Wrap(err, op)
}
}
if opts.newOplogMsg != nil {
msg, err := rw.newOplogMessage(ctx, CreateOp, i)
if err != nil {
return fmt.Errorf("create: returning oplog failed: %w", err)
return errors.Wrap(err, op, errors.WithMsg("returning oplog failed"))
}
*opts.newOplogMsg = *msg
}
if err := rw.lookupAfterWrite(ctx, i, opt...); err != nil {
return fmt.Errorf("create: %w", err)
return errors.Wrap(err, op)
}
return nil
}
@ -297,21 +301,22 @@ func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
// WithOplog and WithOplogMsgs. WithOplog and WithOplogMsgs may not be used
// together. WithLookup is not a supported option.
func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ...Option) error {
const op = "db.CreateItems"
if rw.underlying == nil {
return fmt.Errorf("create items: missing underlying db: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if len(createItems) == 0 {
return fmt.Errorf("create items: no interfaces to create: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing interfaces")
}
opts := GetOpts(opt...)
if opts.withLookup {
return fmt.Errorf("create items: with lookup not a supported option: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "with lookup not a supported option")
}
if opts.newOplogMsg != nil {
return fmt.Errorf("create items: new oplog msg (singular) is not a supported option: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "new oplog msg (singular) is not a supported option")
}
if opts.withOplog && opts.newOplogMsgs != nil {
return fmt.Errorf("create items: both WithOplog and NewOplogMsgs options have been specified: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsgs options have been specified")
}
// verify that createItems are all the same type.
var foundType reflect.Type
@ -321,35 +326,35 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ..
}
currentType := reflect.TypeOf(v)
if foundType != currentType {
return fmt.Errorf("create items: create items contains disparate types. item %d is not a %s: %w", i, foundType.Name(), errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, fmt.Sprintf("create items contains disparate types. item %d is not a %s", i, foundType.Name()))
}
}
var ticket *store.Ticket
if opts.withOplog {
_, err := validateOplogArgs(createItems[0], opts)
if err != nil {
return fmt.Errorf("create items: oplog validation failed: %w", err)
return errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
}
ticket, err = rw.GetTicket(createItems[0])
if err != nil {
return fmt.Errorf("create items: unable to get ticket: %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
}
}
for _, item := range createItems {
if err := rw.Create(ctx, item); err != nil {
return fmt.Errorf("create items: %w", err)
return errors.Wrap(err, op)
}
}
if opts.withOplog {
if err := rw.addOplogForItems(ctx, CreateOp, opts, ticket, createItems); err != nil {
return fmt.Errorf("create items: unable to add oplog: %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to add oplog"))
}
}
if opts.newOplogMsgs != nil {
msgs, err := rw.oplogMsgsForItems(ctx, CreateOp, opts, createItems)
if err != nil {
return fmt.Errorf("create items: returning oplog msgs failed %w", err)
return errors.Wrap(err, op, errors.WithMsg("returning oplog msgs failed"))
}
*opts.newOplogMsgs = append(*opts.newOplogMsgs, msgs...)
}
@ -376,46 +381,47 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ..
// version matches the WithVersion option. Zero is not a valid value for the
// WithVersion option and will return an error.
func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error) {
const op = "db.Update"
if rw.underlying == nil {
return NoRowsAffected, fmt.Errorf("update: missing underlying db %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return NoRowsAffected, fmt.Errorf("update: interface is missing %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing interface")
}
if len(fieldMaskPaths) == 0 && len(setToNullPaths) == 0 {
return NoRowsAffected, stderrors.New("update: both fieldMaskPaths and setToNullPaths are missing")
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both fieldMaskPaths and setToNullPaths are missing")
}
opts := GetOpts(opt...)
withOplog := opts.withOplog
if withOplog && opts.newOplogMsg != nil {
return NoRowsAffected, fmt.Errorf("update: both WithOplog and NewOplogMsg options have been specified: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
}
// we need to filter out some non-updatable fields (like: CreateTime, etc)
fieldMaskPaths = filterPaths(fieldMaskPaths)
setToNullPaths = filterPaths(setToNullPaths)
if len(fieldMaskPaths) == 0 && len(setToNullPaths) == 0 {
return NoRowsAffected, fmt.Errorf("update: after filtering non-updated fields, there are no fields left in fieldMaskPaths or setToNullPaths")
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "after filtering non-updated fields, there are no fields left in fieldMaskPaths or setToNullPaths")
}
updateFields, err := common.UpdateFields(i, fieldMaskPaths, setToNullPaths)
if err != nil {
return NoRowsAffected, fmt.Errorf("update: getting update fields failed: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("getting update fields failed"))
}
if len(updateFields) == 0 {
return NoRowsAffected, fmt.Errorf("update: no fields matched using fieldMaskPaths %s", fieldMaskPaths)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("no fields matched using fieldMaskPaths %s", fieldMaskPaths))
}
// This is not a boundary scope, but rather a gorm Scope:
// https://godoc.org/github.com/jinzhu/gorm#DB.NewScope
scope := rw.underlying.NewScope(i)
if scope.PrimaryKeyZero() {
return NoRowsAffected, fmt.Errorf("update: primary key is not set")
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "primary key is not set")
}
for _, f := range scope.PrimaryFields() {
if contains(fieldMaskPaths, f.Name) {
return NoRowsAffected, fmt.Errorf("update: not allowed on primary key field %s: %w", f.Name, errors.ErrInvalidFieldMask)
return NoRowsAffected, errors.New(errors.InvalidFieldMask, op, fmt.Sprintf("not allowed on primary key field %s", f.Name))
}
}
@ -423,13 +429,13 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
// let's validate oplog options before we start writing to the database
_, err := validateOplogArgs(i, opts)
if err != nil {
return NoRowsAffected, fmt.Errorf("update: oplog validation failed: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
}
}
if !opts.withSkipVetForWrite {
if vetter, ok := i.(VetForWriter); ok {
if err := vetter.VetForWrite(ctx, rw, UpdateOp, WithFieldMaskPaths(fieldMaskPaths), WithNullPaths(setToNullPaths)); err != nil {
return NoRowsAffected, fmt.Errorf("update: vet for write failed: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("vet for write failed"))
}
}
}
@ -438,7 +444,7 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
var err error
ticket, err = rw.GetTicket(i)
if err != nil {
return NoRowsAffected, fmt.Errorf("update: unable to get ticket: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
}
}
var underlying *gorm.DB
@ -448,10 +454,10 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
var args []interface{}
if opts.WithVersion != nil {
if *opts.WithVersion == 0 {
return NoRowsAffected, fmt.Errorf("update: with version option is zero: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "with version option is zero")
}
if _, ok := scope.FieldByName("version"); !ok {
return NoRowsAffected, fmt.Errorf("update: %s does not have a version field", scope.TableName())
return NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s does not have a version field", scope.TableName()))
}
where, args = append(where, "version = ?"), append(args, opts.WithVersion)
}
@ -463,10 +469,10 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
underlying = rw.underlying.Model(i).Updates(updateFields)
}
if underlying.Error != nil {
if err == gorm.ErrRecordNotFound {
return NoRowsAffected, fmt.Errorf("update: failed: %w", errors.ErrRecordNotFound)
if underlying.Error == gorm.ErrRecordNotFound {
return NoRowsAffected, errors.E(errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
}
return NoRowsAffected, fmt.Errorf("update: failed: %w", underlying.Error)
return NoRowsAffected, errors.Wrap(underlying.Error, op)
}
rowsUpdated := int(underlying.RowsAffected)
if rowsUpdated > 0 && (withOplog || opts.newOplogMsg != nil) {
@ -484,13 +490,13 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
}
if withOplog {
if err := rw.addOplog(ctx, UpdateOp, oplogOpts, ticket, i); err != nil {
return rowsUpdated, fmt.Errorf("update: add oplog failed %w", err)
return rowsUpdated, errors.Wrap(err, op, errors.WithMsg("add oplog failed"))
}
}
if opts.newOplogMsg != nil {
msg, err := rw.newOplogMessage(ctx, UpdateOp, i, WithFieldMaskPaths(oplogFieldMasks), WithNullPaths(oplogNullPaths))
if err != nil {
return rowsUpdated, fmt.Errorf("update: returning oplog failed %w", err)
return rowsUpdated, errors.Wrap(err, op, errors.WithMsg("returning oplog failed"))
}
*opts.newOplogMsg = *msg
}
@ -499,7 +505,7 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
// from the db
opt = append(opt, WithLookup(true))
if err := rw.lookupAfterWrite(ctx, i, opt...); err != nil {
return NoRowsAffected, fmt.Errorf("update: %w", err)
return NoRowsAffected, errors.Wrap(err, op)
}
return rowsUpdated, nil
}
@ -510,29 +516,30 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
// WithWhere allows specifying a constraint. Delete returns the number of rows
// deleted and any errors.
func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, error) {
const op = "db.Delete"
if rw.underlying == nil {
return NoRowsAffected, fmt.Errorf("delete: missing underlying db %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return NoRowsAffected, fmt.Errorf("delete: interface is missing %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing interface")
}
opts := GetOpts(opt...)
withOplog := opts.withOplog
if withOplog && opts.newOplogMsg != nil {
return NoRowsAffected, fmt.Errorf("delete: both WithOplog and NewOplogMsg options have been specified: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
}
// This is not a boundary scope, but rather a gorm Scope:
// https://godoc.org/github.com/jinzhu/gorm#DB.NewScope
scope := rw.underlying.NewScope(i)
if opts.withWhereClause == "" {
if scope.PrimaryKeyZero() {
return NoRowsAffected, fmt.Errorf("delete: primary key is not set")
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "primary key is not set")
}
}
if withOplog {
_, err := validateOplogArgs(i, opts)
if err != nil {
return NoRowsAffected, fmt.Errorf("delete: oplog validation failed %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
}
}
var ticket *store.Ticket
@ -540,7 +547,7 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
var err error
ticket, err = rw.GetTicket(i)
if err != nil {
return NoRowsAffected, fmt.Errorf("delete: unable to get ticket: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
}
}
db := rw.underlying
@ -549,19 +556,19 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
}
db = db.Delete(i)
if db.Error != nil {
return NoRowsAffected, fmt.Errorf("delete: failed %w", db.Error)
return NoRowsAffected, errors.Wrap(db.Error, op)
}
rowsDeleted := int(db.RowsAffected)
if rowsDeleted > 0 && (withOplog || opts.newOplogMsg != nil) {
if withOplog {
if err := rw.addOplog(ctx, DeleteOp, opts, ticket, i); err != nil {
return rowsDeleted, fmt.Errorf("delete: add oplog failed %w", err)
return rowsDeleted, errors.Wrap(db.Error, op, errors.WithMsg("add oplog failed"))
}
}
if opts.newOplogMsg != nil {
msg, err := rw.newOplogMessage(ctx, DeleteOp, i)
if err != nil {
return rowsDeleted, fmt.Errorf("delete: returning oplog failed %w", err)
return rowsDeleted, errors.Wrap(db.Error, op, errors.WithMsg("returning oplog failed"))
}
*opts.newOplogMsg = *msg
}
@ -573,18 +580,19 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
// WithOplog and WithOplogMsgs. WithOplog and WithOplogMsgs may not be used
// together.
func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ...Option) (int, error) {
const op = "db.DeleteItems"
if rw.underlying == nil {
return NoRowsAffected, fmt.Errorf("delete items: missing underlying db: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if len(deleteItems) == 0 {
return NoRowsAffected, fmt.Errorf("delete items: no interfaces to delete: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "no interfaces to delete")
}
opts := GetOpts(opt...)
if opts.newOplogMsg != nil {
return NoRowsAffected, fmt.Errorf("delete items: new oplog msg (singular) is not a supported option: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "new oplog msg (singular) is not a supported option")
}
if opts.withOplog && opts.newOplogMsgs != nil {
return NoRowsAffected, fmt.Errorf("delete items: both WithOplog and NewOplogMsgs options have been specified: %w", errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsgs options have been specified")
}
// verify that createItems are all the same type.
var foundType reflect.Type
@ -594,7 +602,7 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
}
currentType := reflect.TypeOf(v)
if foundType != currentType {
return NoRowsAffected, fmt.Errorf("delete items: items contain disparate types. item %d is not a %s: %w", i, foundType.Name(), errors.ErrInvalidParameter)
return NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("items contain disparate types. item %d is not a %s", i, foundType.Name()))
}
}
@ -602,11 +610,11 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
if opts.withOplog {
_, err := validateOplogArgs(deleteItems[0], opts)
if err != nil {
return NoRowsAffected, fmt.Errorf("delete items: oplog validation failed: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
}
ticket, err = rw.GetTicket(deleteItems[0])
if err != nil {
return NoRowsAffected, fmt.Errorf("delete items: unable to get ticket: %w", err)
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
}
}
rowsDeleted := 0
@ -616,20 +624,20 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
// relationship between Create and CreateItems).
underlying := rw.underlying.Delete(item)
if underlying.Error != nil {
return rowsDeleted, fmt.Errorf("delete: failed: %w", underlying.Error)
return rowsDeleted, errors.Wrap(underlying.Error, op)
}
rowsDeleted += int(underlying.RowsAffected)
}
if rowsDeleted > 0 && (opts.withOplog || opts.newOplogMsgs != nil) {
if opts.withOplog {
if err := rw.addOplogForItems(ctx, DeleteOp, opts, ticket, deleteItems); err != nil {
return rowsDeleted, fmt.Errorf("delete items: unable to add oplog: %w", err)
return rowsDeleted, errors.Wrap(err, op, errors.WithMsg("unable to add oplog"))
}
}
if opts.newOplogMsgs != nil {
msgs, err := rw.oplogMsgsForItems(ctx, DeleteOp, opts, deleteItems)
if err != nil {
return rowsDeleted, fmt.Errorf("delete items: returning oplog msgs failed %w", err)
return rowsDeleted, errors.Wrap(err, op, errors.WithMsg("returning oplog msgs failed"))
}
*opts.newOplogMsgs = append(*opts.newOplogMsgs, msgs...)
}
@ -638,31 +646,33 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
}
func validateOplogArgs(i interface{}, opts Options) (oplog.ReplayableMessage, error) {
const op = "db.validateOplogArgs"
oplogArgs := opts.oplogOpts
if oplogArgs.wrapper == nil {
return nil, fmt.Errorf("error no wrapper WithOplog: %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "missing wrapper")
}
if len(oplogArgs.metadata) == 0 {
return nil, fmt.Errorf("error no metadata for WithOplog: %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "missing metadata")
}
replayable, ok := i.(oplog.ReplayableMessage)
if !ok {
return nil, stderrors.New("error not a replayable message for WithOplog")
return nil, errors.E(errors.WithOp(op), errors.WithMsg("not a replayable message"))
}
return replayable, nil
}
func (rw *Db) getTicketFor(aggregateName string) (*store.Ticket, error) {
const op = "db.getTicketFor"
if rw.underlying == nil {
return nil, fmt.Errorf("get ticket for %s: underlying db missing: %w", aggregateName, errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s: underlying db missing", aggregateName))
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return nil, fmt.Errorf("get ticket for %s: unable to get Ticketer %w", aggregateName, err)
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get Ticketer", aggregateName)))
}
ticket, err := ticketer.GetTicket(aggregateName)
if err != nil {
return nil, fmt.Errorf("get ticket for %s: unable to get ticket %w", aggregateName, err)
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get ticket", aggregateName)))
}
return ticket, nil
}
@ -670,22 +680,24 @@ func (rw *Db) getTicketFor(aggregateName string) (*store.Ticket, error) {
// GetTicket returns an oplog ticket for the aggregate root of "i" which can
// be used to WriteOplogEntryWith for that aggregate root.
func (rw *Db) GetTicket(i interface{}) (*store.Ticket, error) {
const op = "db.GetTicket"
if rw.underlying == nil {
return nil, fmt.Errorf("get ticket: underlying db missing: %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return nil, fmt.Errorf("get ticket: interface is missing %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "missing interface")
}
replayable, ok := i.(oplog.ReplayableMessage)
if !ok {
return nil, fmt.Errorf("get ticket: not a replayable message %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "not a replayable message")
}
return rw.getTicketFor(replayable.TableName())
}
func (rw *Db) oplogMsgsForItems(ctx context.Context, opType OpType, opts Options, items []interface{}) ([]*oplog.Message, error) {
const op = "db.oplogMsgsForItems"
if len(items) == 0 {
return nil, fmt.Errorf("oplog msgs for items: items is empty: %w", errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, "missing items")
}
oplogMsgs := []*oplog.Message{}
var foundType reflect.Type
@ -695,11 +707,11 @@ func (rw *Db) oplogMsgsForItems(ctx context.Context, opType OpType, opts Options
}
currentType := reflect.TypeOf(item)
if foundType != currentType {
return nil, fmt.Errorf("oplog msgs for items: items contains disparate types. item (%d) %s is not a %s: %w", i, currentType, foundType, errors.ErrInvalidParameter)
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("items contains disparate types. item (%d) %s is not a %s", i, currentType, foundType))
}
msg, err := rw.newOplogMessage(ctx, opType, item, WithFieldMaskPaths(opts.WithFieldMaskPaths), WithNullPaths(opts.WithNullPaths))
if err != nil {
return nil, fmt.Errorf("oplog msgs for items: %w", err)
return nil, errors.Wrap(err, op)
}
oplogMsgs = append(oplogMsgs, msg)
}
@ -710,35 +722,33 @@ func (rw *Db) oplogMsgsForItems(ctx context.Context, opType OpType, opts Options
// item. Items must all be of the same type. Only CreateOp and DeleteOp are
// currently supported operations.
func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options, ticket *store.Ticket, items []interface{}) error {
const op = "db.addOplogForItems"
oplogArgs := opts.oplogOpts
if ticket == nil {
return fmt.Errorf("oplog for items: ticket is missing: %w", errors.ErrInvalidParameter)
}
if items == nil {
return fmt.Errorf("oplog for items: items are missing: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing ticket")
}
if len(items) == 0 {
return fmt.Errorf("oplog for items: items is empty: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing items")
}
if oplogArgs.metadata == nil {
return fmt.Errorf("oplog for items: metadata is missing: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing metadata")
}
if oplogArgs.wrapper == nil {
return fmt.Errorf("oplog for items: wrapper is missing: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing wrapper")
}
oplogMsgs, err := rw.oplogMsgsForItems(ctx, opType, opts, items)
if err != nil {
return fmt.Errorf("oplog for items: %w", err)
return errors.Wrap(err, op)
}
replayable, err := validateOplogArgs(items[0], opts)
if err != nil {
return fmt.Errorf("oplog for items: oplog validation failed %w", err)
return errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return fmt.Errorf("oplog for items: unable to get Ticketer %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to get Ticketer"))
}
entry, err := oplog.NewEntry(
replayable.TableName(),
@ -747,7 +757,7 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
ticketer,
)
if err != nil {
return fmt.Errorf("oplog for items: unable to create oplog entry %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to create oplog entry"))
}
if err := entry.WriteEntryWith(
ctx,
@ -755,23 +765,24 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
ticket,
oplogMsgs...,
); err != nil {
return fmt.Errorf("oplog for items: unable to write oplog entry %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog entry"))
}
return nil
}
func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket *store.Ticket, i interface{}) error {
const op = "db.addOplog"
oplogArgs := opts.oplogOpts
replayable, err := validateOplogArgs(i, opts)
if err != nil {
return err
return errors.Wrap(err, op)
}
if ticket == nil {
return fmt.Errorf("add oplog: missing ticket %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing ticket")
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return fmt.Errorf("add oplog: unable to get Ticketer %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to get Ticketer"))
}
entry, err := oplog.NewEntry(
replayable.TableName(),
@ -784,7 +795,7 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
}
msg, err := rw.newOplogMessage(ctx, opType, i, WithFieldMaskPaths(opts.WithFieldMaskPaths), WithNullPaths(opts.WithNullPaths))
if err != nil {
return fmt.Errorf("add oplog: %w", err)
return errors.Wrap(err, op)
}
err = entry.WriteEntryWith(
ctx,
@ -793,36 +804,34 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
msg,
)
if err != nil {
return fmt.Errorf("add oplog: unable to write oplog entry: %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog entry"))
}
return nil
}
// WriteOplogEntryWith will write an oplog entry with the msgs provided for
// the ticket's aggregateName. No options are currently supported.
func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper, ticket *store.Ticket, metadata oplog.Metadata, msgs []*oplog.Message, opt ...Option) error {
func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper, ticket *store.Ticket, metadata oplog.Metadata, msgs []*oplog.Message, _ ...Option) error {
const op = "db.WriteOplogEntryWith"
if wrapper == nil {
return fmt.Errorf("write oplog: wrapper is unset %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing wrapper")
}
if ticket == nil {
return fmt.Errorf("write oplog: ticket is unset %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing ticket")
}
if len(msgs) == 0 {
return fmt.Errorf("write oplog: msgs are empty %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing msgs")
}
if rw.underlying == nil {
return fmt.Errorf("write oplog: underlying is unset %w", errors.ErrInvalidParameter)
}
if metadata == nil {
return fmt.Errorf("write oplog: metadata is unset %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if len(metadata) == 0 {
return fmt.Errorf("write oplog: metadata is empty %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing metadata")
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return fmt.Errorf("write oplog: unable to get Ticketer %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to get Ticketer"))
}
entry, err := oplog.NewEntry(
@ -832,7 +841,7 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
ticketer,
)
if err != nil {
return fmt.Errorf("write oplog: unable to create oplog entry: %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to create oplog entry"))
}
err = entry.WriteEntryWith(
ctx,
@ -841,16 +850,17 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
msgs...,
)
if err != nil {
return fmt.Errorf("write oplog: unable to write oplog entry: %w", err)
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog entry"))
}
return nil
}
func (rw *Db) newOplogMessage(ctx context.Context, opType OpType, i interface{}, opt ...Option) (*oplog.Message, error) {
func (rw *Db) newOplogMessage(_ context.Context, opType OpType, i interface{}, opt ...Option) (*oplog.Message, error) {
const op = "db.newOplogMessage"
opts := GetOpts(opt...)
replayable, ok := i.(oplog.ReplayableMessage)
if !ok {
return nil, stderrors.New("error not a replayable interface")
return nil, errors.New(errors.InvalidParameter, op, "not a replayable interface")
}
msg := oplog.Message{
Message: i.(proto.Message),
@ -866,7 +876,7 @@ func (rw *Db) newOplogMessage(ctx context.Context, opType OpType, i interface{},
case DeleteOp:
msg.OpType = oplog.OpType_OP_TYPE_DELETE
default:
return nil, fmt.Errorf("operation type %v is not supported", opType)
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("operation type %v is not supported", opType))
}
return &msg, nil
}
@ -876,13 +886,14 @@ func (rw *Db) newOplogMessage(ctx context.Context, opType OpType, i interface{},
// means that the object may be sent to the db several times (retried), so things like the primary key must
// be reset before retry
func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler TxHandler) (RetryInfo, error) {
const op = "db.DoTx"
if w.underlying == nil {
return RetryInfo{}, stderrors.New("do underlying db is nil")
return RetryInfo{}, errors.New(errors.InvalidParameter, op, "missing underlying db")
}
info := RetryInfo{}
for attempts := uint(1); ; attempts++ {
if attempts > retries+1 {
return info, fmt.Errorf("Too many retries: %d of %d", attempts-1, retries+1)
return info, errors.New(errors.MaxRetries, op, fmt.Sprintf("Too many retries: %d of %d", attempts-1, retries+1))
}
// step one of this, start a transaction...
@ -891,7 +902,7 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
rw := &Db{newTx}
if err := Handler(rw, rw); err != nil {
if err := newTx.Rollback().Error; err != nil {
return info, err
return info, errors.Wrap(err, op)
}
if errors.Is(err, oplog.ErrTicketAlreadyRedeemed) {
d := backOff.Duration(attempts)
@ -900,14 +911,14 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
time.Sleep(d)
continue
}
return info, err
return info, errors.Wrap(err, op)
}
if err := newTx.Commit().Error; err != nil {
if err := newTx.Rollback().Error; err != nil {
return info, err
return info, errors.Wrap(err, op)
}
return info, err
return info, errors.Wrap(err, op)
}
return info, nil // it all worked!!!
}
@ -915,27 +926,29 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
// LookupByPublicId will lookup resource by its public_id or private_id, which
// must be unique. Options are ignored.
func (rw *Db) LookupById(ctx context.Context, resourceWithIder interface{}, opt ...Option) error {
func (rw *Db) LookupById(_ context.Context, resourceWithIder interface{}, _ ...Option) error {
const op = "db.LookupById"
if rw.underlying == nil {
return fmt.Errorf("lookup by id: underlying db nil %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if reflect.ValueOf(resourceWithIder).Kind() != reflect.Ptr {
return fmt.Errorf("lookup by id: interface parameter must to be a pointer: %w", errors.ErrInvalidParameter)
return errors.New(errors.InvalidParameter, op, "interface parameter must to be a pointer")
}
primaryKey, where, err := primaryKeyWhere(resourceWithIder)
if err != nil {
return fmt.Errorf("lookup by id: %w", err)
return errors.Wrap(err, op)
}
if err := rw.underlying.Where(where, primaryKey).First(resourceWithIder).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return errors.ErrRecordNotFound
return errors.E(errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
}
return err
return errors.Wrap(err, op)
}
return nil
}
func primaryKeyWhere(resourceWithIder interface{}) (pkey string, w string, e error) {
const op = "db.primaryKeyWhere"
var primaryKey, where string
switch resourceType := resourceWithIder.(type) {
case ResourcePublicIder:
@ -945,10 +958,10 @@ func primaryKeyWhere(resourceWithIder interface{}) (pkey string, w string, e err
primaryKey = resourceType.GetPrivateId()
where = "private_id = ?"
default:
return "", "", fmt.Errorf("unsupported interface type %w", errors.ErrInvalidParameter)
return "", "", errors.New(errors.InvalidParameter, op, fmt.Sprintf("unsupported interface type %T", resourceWithIder))
}
if primaryKey == "" {
return "", "", fmt.Errorf("primary key unset %w", errors.ErrInvalidParameter)
return "", "", errors.New(errors.InvalidParameter, op, "missing primary key")
}
return primaryKey, where, nil
}
@ -960,16 +973,17 @@ func (rw *Db) LookupByPublicId(ctx context.Context, resource ResourcePublicIder,
}
// LookupWhere will lookup the first resource using a where clause with parameters (it only returns the first one)
func (rw *Db) LookupWhere(ctx context.Context, resource interface{}, where string, args ...interface{}) error {
func (rw *Db) LookupWhere(_ context.Context, resource interface{}, where string, args ...interface{}) error {
const op = "db.LookupWhere"
if rw.underlying == nil {
return stderrors.New("error underlying db nil for lookup by")
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if reflect.ValueOf(resource).Kind() != reflect.Ptr {
return stderrors.New("error interface parameter must to be a pointer for lookup by")
return errors.New(errors.InvalidParameter, op, "interface parameter must to be a pointer")
}
if err := rw.underlying.Where(where, args...).First(resource).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return errors.ErrRecordNotFound
return errors.E(errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
}
return err
}
@ -980,13 +994,14 @@ func (rw *Db) LookupWhere(ctx context.Context, resource interface{}, where strin
// clause with parameters. Supports the WithLimit option. If
// WithLimit < 0, then unlimited results are returned. If WithLimit == 0, then
// default limits are used for results. Supports the WithOrder option.
func (rw *Db) SearchWhere(ctx context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error {
func (rw *Db) SearchWhere(_ context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error {
const op = "db.SearchWhere"
opts := GetOpts(opt...)
if rw.underlying == nil {
return stderrors.New("error underlying db nil for search by")
return errors.New(errors.InvalidParameter, op, "missing underlying db")
}
if reflect.ValueOf(resources).Kind() != reflect.Ptr {
return stderrors.New("error interface parameter must to be a pointer for search by")
return errors.New(errors.InvalidParameter, op, "interface parameter must to be a pointer")
}
var err error
db := rw.underlying.Order(opts.withOrder)
@ -1011,7 +1026,7 @@ func (rw *Db) SearchWhere(ctx context.Context, resources interface{}, where stri
err = db.Find(resources).Error
if err != nil {
// searching with a slice parameter does not return a gorm.ErrRecordNotFound
return err
return errors.Wrap(err, op)
}
return nil
}
@ -1070,6 +1085,7 @@ func contains(ss []string, t string) bool {
// A depth of 2 will change i and i's children. A depth of 1 will change i
// but no children of i. A depth of 0 will return with no changes to i.
func Clear(i interface{}, fields []string, depth int) error {
const op = "db.Clear"
if len(fields) == 0 || depth == 0 {
return nil
}
@ -1081,13 +1097,13 @@ func Clear(i interface{}, fields []string, depth int) error {
v := reflect.ValueOf(i)
switch v.Kind() {
default:
return errors.ErrInvalidParameter
case reflect.Ptr:
if v.IsNil() || v.Elem().Kind() != reflect.Struct {
return errors.ErrInvalidParameter
return errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp(op))
}
clear(v, fm, depth)
default:
return errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp(op))
}
return nil
}

@ -129,7 +129,7 @@ func TestDb_Update(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrMsg: "update: with version option is zero: invalid parameter:",
wantErrMsg: "db.Update: with version option is zero: parameter violation: error #100",
},
{
name: "simple-with-version",
@ -213,7 +213,7 @@ func TestDb_Update(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrMsg: `update: failed: pq: column "foo" does not exist`,
wantErrMsg: `db.Update: column "foo" does not exist: integrity violation: error #1102`,
},
{
name: "multiple-null",
@ -276,7 +276,7 @@ func TestDb_Update(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrMsg: "update: not allowed on primary key field Id: invalid field mask:",
wantErrMsg: "db.Update: not allowed on primary key field Id: parameter violation: error #103",
},
{
name: "both are missing",
@ -293,7 +293,7 @@ func TestDb_Update(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrMsg: "update: both fieldMaskPaths and setToNullPaths are missing",
wantErrMsg: "db.Update: both fieldMaskPaths and setToNullPaths are missing: parameter violation: error #100",
},
{
name: "i is nil",
@ -304,7 +304,7 @@ func TestDb_Update(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrMsg: "update: interface is missing invalid parameter:",
wantErrMsg: "db.Update: missing interface: parameter violation: error #100",
},
{
name: "only read-only",
@ -321,7 +321,7 @@ func TestDb_Update(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrMsg: "update: after filtering non-updated fields, there are no fields left in fieldMaskPaths or setToNullPaths",
wantErrMsg: "db.Update: after filtering non-updated fields, there are no fields left in fieldMaskPaths or setToNullPaths: parameter violation: error #100",
},
}
for _, tt := range tests {
@ -444,7 +444,7 @@ func TestDb_Update(t *testing.T) {
)
require.Error(err)
assert.Equal(0, rowsUpdated)
assert.True(errors.Is(err, errors.ErrInvalidParameter))
assert.True(errors.Match(errors.T(errors.InvalidParameter), err))
})
t.Run("valid-NewOplogMsg", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -530,7 +530,7 @@ func TestDb_Update(t *testing.T) {
rowsUpdated, err := w.Update(context.Background(), user, []string{"Name"}, nil)
assert.Error(err)
assert.Equal(0, rowsUpdated)
assert.Contains(err.Error(), "update: missing underlying db invalid parameter:")
assert.Contains(err.Error(), "db.Update: missing underlying db: parameter violation: error #100")
})
t.Run("no-wrapper-WithOplog", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -552,7 +552,7 @@ func TestDb_Update(t *testing.T) {
)
require.Error(err)
assert.Equal(0, rowsUpdated)
assert.Contains(err.Error(), "update: oplog validation failed: error no wrapper WithOplog: invalid parameter:")
assert.Contains(err.Error(), "db.Update: oplog validation failed: db.validateOplogArgs: missing wrapper: parameter violation: error #100")
})
t.Run("no-metadata-WithOplog", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -569,7 +569,7 @@ func TestDb_Update(t *testing.T) {
)
require.Error(err)
assert.Equal(0, rowsUpdated)
assert.Contains(err.Error(), "update: oplog validation failed: error no metadata for WithOplog: invalid parameter:")
assert.Contains(err.Error(), "db.Update: oplog validation failed: db.validateOplogArgs: missing metadata: parameter violation: error #100")
})
}
@ -684,7 +684,7 @@ func TestDb_Create(t *testing.T) {
WithOplog(TestWrapper(t), oplog.Metadata{"alice": []string{"bob"}}),
)
require.Error(err)
assert.True(errors.Is(err, errors.ErrInvalidParameter))
assert.True(errors.Match(errors.T(errors.InvalidParameter), err))
})
t.Run("valid-NewOplogMsg", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -750,7 +750,7 @@ func TestDb_Create(t *testing.T) {
),
)
require.Error(err)
assert.Contains(err.Error(), "create: oplog validation failed: error no wrapper WithOplog: invalid parameter")
assert.Contains(err.Error(), "db.Create: oplog validation failed: db.validateOplogArgs: missing wrapper: parameter violation: error #100")
})
t.Run("no-metadata-WithOplog", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -769,7 +769,7 @@ func TestDb_Create(t *testing.T) {
),
)
require.Error(err)
assert.Contains(err.Error(), "create: oplog validation failed: error no metadata for WithOplog: invalid parameter")
assert.Contains(err.Error(), "db.Create: oplog validation failed: db.validateOplogArgs: missing metadata: parameter violation: error #100")
})
t.Run("nil-tx", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -781,7 +781,7 @@ func TestDb_Create(t *testing.T) {
user.Name = "foo-" + id
err = w.Create(context.Background(), user)
require.Error(err)
assert.Contains(err.Error(), "create: missing underlying db: invalid parameter")
assert.Contains(err.Error(), "db.Create: missing underlying db: parameter violation: error #100")
})
}
@ -814,7 +814,7 @@ func TestDb_LookupByPublicId(t *testing.T) {
require.NoError(err)
err = w.LookupByPublicId(context.Background(), foundUser)
require.Error(err)
assert.Contains(err.Error(), "lookup by id: underlying db nil invalid parameter")
assert.Contains(err.Error(), "db.LookupById: missing underlying db: parameter violation: error #100")
})
t.Run("no-public-id-set", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -824,7 +824,7 @@ func TestDb_LookupByPublicId(t *testing.T) {
require.NoError(err)
err = w.LookupByPublicId(context.Background(), foundUser)
require.Error(err)
assert.Contains(err.Error(), "lookup by id: primary key unset invalid parameter")
assert.Contains(err.Error(), "db.LookupById: db.primaryKeyWhere: missing primary key: parameter violation: error #100")
})
t.Run("not-found", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -836,7 +836,7 @@ func TestDb_LookupByPublicId(t *testing.T) {
foundUser.PublicId = id
err = w.LookupByPublicId(context.Background(), foundUser)
require.Error(err)
assert.Equal(errors.ErrRecordNotFound, err)
assert.True(errors.Match(errors.T(errors.RecordNotFound), err))
})
}
@ -866,7 +866,7 @@ func TestDb_LookupWhere(t *testing.T) {
var foundUser db_test.TestUser
err := w.LookupWhere(context.Background(), &foundUser, "public_id = ?", 1)
require.Error(err)
assert.Equal("error underlying db nil for lookup by", err.Error())
assert.Equal("db.LookupWhere: missing underlying db: parameter violation: error #100", err.Error())
})
t.Run("not-found", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -877,8 +877,7 @@ func TestDb_LookupWhere(t *testing.T) {
var foundUser db_test.TestUser
err = w.LookupWhere(context.Background(), &foundUser, "public_id = ?", id)
require.Error(err)
assert.Equal(errors.ErrRecordNotFound, err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.Match(errors.T(errors.RecordNotFound), err))
})
t.Run("bad-where", func(t *testing.T) {
require := require.New(t)
@ -1113,7 +1112,7 @@ func TestDb_DoTx(t *testing.T) {
got, err := w.DoTx(context.Background(), 1, ExpBackoff{}, func(Reader, Writer) error { attempts += 1; return nil })
require.Error(err)
assert.Equal(RetryInfo{}, got)
assert.Equal("do underlying db is nil", err.Error())
assert.Equal("db.DoTx: missing underlying db: parameter violation: error #100", err.Error())
})
t.Run("not-a-retry-err", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -1130,7 +1129,7 @@ func TestDb_DoTx(t *testing.T) {
got, err := w.DoTx(context.Background(), 2, ExpBackoff{}, func(Reader, Writer) error { attempts += 1; return oplog.ErrTicketAlreadyRedeemed })
require.Error(err)
assert.Equal(3, got.Retries)
assert.Equal("Too many retries: 3 of 3", err.Error())
assert.Equal("db.DoTx: Too many retries: 3 of 3: db transaction issue: error #1103", err.Error())
})
t.Run("updating-good-bad-good", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -1238,7 +1237,7 @@ func TestDb_Delete(t *testing.T) {
want int
wantOplog bool
wantErr bool
wantErrIs error
wantErrIs errors.Code
}{
{
name: "simple-no-oplog",
@ -1273,7 +1272,7 @@ func TestDb_Delete(t *testing.T) {
wantOplog: true,
want: 0,
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil-metadata",
@ -1286,7 +1285,7 @@ func TestDb_Delete(t *testing.T) {
wantOplog: true,
want: 0,
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil-underlying",
@ -1297,7 +1296,7 @@ func TestDb_Delete(t *testing.T) {
},
want: 0,
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "not-found",
@ -1326,8 +1325,8 @@ func TestDb_Delete(t *testing.T) {
assert.Equal(tt.want, got)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "received unexpected error: %v", err)
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "received unexpected error: %v", err)
}
err := TestVerifyOplog(t, rw, tt.args.i.GetPublicId(), WithOperation(oplog.OpType_OP_TYPE_DELETE), WithCreateNotBefore(5*time.Second))
assert.Error(err)
@ -1340,7 +1339,7 @@ func TestDb_Delete(t *testing.T) {
foundUser.PublicId = tt.args.i.PublicId
err = rw.LookupByPublicId(context.Background(), foundUser)
assert.Error(err)
assert.Equal(errors.ErrRecordNotFound, err)
assert.True(errors.Match(errors.T(errors.RecordNotFound), err))
err = TestVerifyOplog(t, rw, tt.args.i.GetPublicId(), WithOperation(oplog.OpType_OP_TYPE_DELETE), WithCreateNotBefore(5*time.Second))
switch {
@ -1370,7 +1369,7 @@ func TestDb_Delete(t *testing.T) {
rowsDeleted, err := w.Delete(context.Background(), user, NewOplogMsg(&deleteMsg), WithOplog(TestWrapper(t), oplog.Metadata{"alice": []string{"bob"}}))
require.Error(err)
assert.Equal(0, rowsDeleted)
assert.True(errors.Is(err, errors.ErrInvalidParameter))
assert.True(errors.Match(errors.T(errors.InvalidParameter), err))
})
t.Run("valid-NewOplogMsg", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -1402,7 +1401,7 @@ func TestDb_Delete(t *testing.T) {
foundUser.PublicId = user.PublicId
err = w.LookupByPublicId(context.Background(), foundUser)
require.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.Match(errors.T(errors.RecordNotFound), err))
metadata := oplog.Metadata{
"resource-public-id": []string{user.PublicId},
@ -1509,7 +1508,7 @@ func TestDb_CreateItems(t *testing.T) {
wantOplogId string
wantOplogMsgs bool
wantErr bool
wantErrIs error
wantErrIs errors.Code
}{
{
name: "simple",
@ -1565,7 +1564,7 @@ func TestDb_CreateItems(t *testing.T) {
),
},
},
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
wantErr: true,
},
{
@ -1575,7 +1574,7 @@ func TestDb_CreateItems(t *testing.T) {
createItems: createMixedFn(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad oplog opt: nil metadata",
@ -1590,7 +1589,7 @@ func TestDb_CreateItems(t *testing.T) {
},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad oplog opt: nil wrapper",
@ -1608,7 +1607,7 @@ func TestDb_CreateItems(t *testing.T) {
},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad opt: WithLookup",
@ -1618,7 +1617,7 @@ func TestDb_CreateItems(t *testing.T) {
opt: []Option{WithLookup(true)},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil underlying",
@ -1627,7 +1626,7 @@ func TestDb_CreateItems(t *testing.T) {
createItems: createFn(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "empty items",
@ -1636,7 +1635,7 @@ func TestDb_CreateItems(t *testing.T) {
createItems: []interface{}{},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil items",
@ -1645,7 +1644,7 @@ func TestDb_CreateItems(t *testing.T) {
createItems: nil,
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -1657,8 +1656,8 @@ func TestDb_CreateItems(t *testing.T) {
err := rw.CreateItems(context.Background(), tt.args.createItems, tt.args.opt...)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error: %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error: %s", err.Error())
}
return
}
@ -1713,7 +1712,7 @@ func TestDb_DeleteItems(t *testing.T) {
wantOplogId string
wantOplogMsgs bool
wantErr bool
wantErrIs error
wantErrIs errors.Code
}{
{
name: "simple",
@ -1753,7 +1752,7 @@ func TestDb_DeleteItems(t *testing.T) {
},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "withOplog",
@ -1787,7 +1786,7 @@ func TestDb_DeleteItems(t *testing.T) {
},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad oplog opt: nil wrapper",
@ -1805,7 +1804,7 @@ func TestDb_DeleteItems(t *testing.T) {
},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad opt: WithLookup",
@ -1815,7 +1814,7 @@ func TestDb_DeleteItems(t *testing.T) {
opt: []Option{WithLookup(true)},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil underlying",
@ -1824,7 +1823,7 @@ func TestDb_DeleteItems(t *testing.T) {
deleteItems: createFn(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "empty items",
@ -1833,7 +1832,7 @@ func TestDb_DeleteItems(t *testing.T) {
deleteItems: []interface{}{},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil items",
@ -1842,7 +1841,7 @@ func TestDb_DeleteItems(t *testing.T) {
deleteItems: nil,
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -1854,8 +1853,8 @@ func TestDb_DeleteItems(t *testing.T) {
rowsDeleted, err := rw.DeleteItems(context.Background(), tt.args.deleteItems, tt.args.opt...)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error: %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error: %s", err.Error())
}
return
}
@ -1866,7 +1865,7 @@ func TestDb_DeleteItems(t *testing.T) {
u.PublicId = item.(*db_test.TestUser).PublicId
err := rw.LookupByPublicId(context.Background(), &u)
require.Error(err)
require.Truef(errors.Is(err, errors.ErrRecordNotFound), "found item %s that should be deleted", u.PublicId)
require.Truef(errors.Match(errors.T(errors.RecordNotFound), err), "found item %s that should be deleted", u.PublicId)
}
if tt.wantOplogId != "" {
err = TestVerifyOplog(t, rw, tt.wantOplogId, WithOperation(oplog.OpType_OP_TYPE_DELETE), WithCreateNotBefore(10*time.Second))
@ -1966,7 +1965,7 @@ func TestDb_LookupById(t *testing.T) {
args args
wantErr bool
want proto.Message
wantIsErr error
wantIsErr errors.Code
}{
{
name: "simple-private-id",
@ -1995,7 +1994,7 @@ func TestDb_LookupById(t *testing.T) {
},
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "missing-private-id",
@ -2006,7 +2005,7 @@ func TestDb_LookupById(t *testing.T) {
},
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "not-an-ider",
@ -2015,7 +2014,7 @@ func TestDb_LookupById(t *testing.T) {
resourceWithIder: &db_test.NotIder{},
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "missing-underlying-db",
@ -2024,7 +2023,7 @@ func TestDb_LookupById(t *testing.T) {
resourceWithIder: user,
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -2039,7 +2038,7 @@ func TestDb_LookupById(t *testing.T) {
err := rw.LookupById(context.Background(), cp, tt.args.opt...)
if tt.wantErr {
require.Error(err)
require.True(errors.Is(err, tt.wantIsErr))
require.True(errors.Match(errors.T(tt.wantIsErr), err))
return
}
require.NoError(err)
@ -2053,7 +2052,7 @@ func TestDb_LookupById(t *testing.T) {
}
err := rw.LookupById(context.Background(), *u)
require.Error(t, err)
assert.True(t, errors.Is(err, errors.ErrInvalidParameter))
assert.True(t, errors.Match(errors.T(errors.InvalidParameter), err))
})
}
@ -2065,7 +2064,7 @@ func TestDb_GetTicket(t *testing.T) {
underlying *gorm.DB
aggregateType interface{}
wantErr bool
wantErrIs error
wantErrIs errors.Code
}{
{
name: "simple",
@ -2078,21 +2077,21 @@ func TestDb_GetTicket(t *testing.T) {
underlying: db,
aggregateType: &notReplayable{},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil-aggregate-type",
underlying: db,
aggregateType: nil,
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "no-underlying",
underlying: nil,
aggregateType: &db_test.TestUser{},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -2104,8 +2103,8 @@ func TestDb_GetTicket(t *testing.T) {
got, err := rw.GetTicket(tt.aggregateType)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error type: %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error type: %s", err.Error())
}
return
}
@ -2153,7 +2152,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
underlying *gorm.DB
args args
wantErr bool
wantErrIs error
wantErrIs errors.Code
wantErrContains string
}{
{
@ -2188,7 +2187,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
msgs: []*oplog.Message{&createMsg},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "missing-db",
@ -2200,7 +2199,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
msgs: []*oplog.Message{&createMsg},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "missing-wrapper",
@ -2212,7 +2211,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
msgs: []*oplog.Message{&createMsg},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "nil-metadata",
@ -2224,7 +2223,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
msgs: []*oplog.Message{&createMsg},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "empty-metadata",
@ -2236,7 +2235,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
msgs: []*oplog.Message{&createMsg},
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -2248,8 +2247,8 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
err := rw.WriteOplogEntryWith(context.Background(), tt.args.wrapper, tt.args.ticket, tt.args.metadata, tt.args.msgs, tt.args.opt...)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error %s", err.Error())
}
if tt.wantErrContains != "" {
assert.Contains(err.Error(), tt.wantErrContains)
@ -2787,7 +2786,7 @@ func TestDb_oplogMsgsForItems(t *testing.T) {
args args
want []*oplog.Message
wantErr bool
wantIsErr error
wantIsErr errors.Code
}{
{
name: "valid",
@ -2805,7 +2804,7 @@ func TestDb_oplogMsgsForItems(t *testing.T) {
items: nil,
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "zero items",
@ -2814,7 +2813,7 @@ func TestDb_oplogMsgsForItems(t *testing.T) {
items: []interface{}{},
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "mixed items",
@ -2823,7 +2822,7 @@ func TestDb_oplogMsgsForItems(t *testing.T) {
items: mixed,
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "bad op",
@ -2840,8 +2839,8 @@ func TestDb_oplogMsgsForItems(t *testing.T) {
got, err := rw.oplogMsgsForItems(context.Background(), tt.args.opType, tt.args.opts, tt.args.items)
if tt.wantErr {
require.Error(err)
if tt.wantIsErr != nil {
assert.Truef(errors.Is(err, tt.wantIsErr), "unexpected error %s", err.Error())
if tt.wantIsErr != 0 {
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "unexpected error %s", err.Error())
}
return
}

@ -27,6 +27,21 @@ const (
InvalidFieldMask Code = 103 // InvalidFieldMask represents an invalid field mast for an operation
EmptyFieldMask Code = 104 // EmptyFieldMask represents an empty field mask for an operation
// PasswordTooShort results from attempting to set a password which is to short.
PasswordTooShort Code = 200
// PasswordUnsupportedConfiguration results from attempting to perform an
// operation that sets a password configuration to an unsupported type.
PasswordUnsupportedConfiguration Code = 201
// PasswordInvalidConfiguration results from attempting to perform an
// operation that sets a valid password configuration with invalid settings.
PasswordInvalidConfiguration Code = 202
// PasswordsEqual is returned from ChangePassword when the old and
// new passwords are equal.
PasswordsEqual Code = 203
// DB errors are reserved Codes from 1000-1999
CheckConstraint Code = 1000 // CheckConstraint represents a check constraint error
NotNull Code = 1001 // NotNull represents a value must not be null error
@ -35,5 +50,7 @@ const (
MissingTable Code = 1004 // Missing table represents an undefined table error
RecordNotFound Code = 1100 // RecordNotFound represents that a record/row was not found matching the criteria
MultipleRecords Code = 1101 // MultipleRecords represents that multiple records/rows were found matching the criteria
ColumnNotFound Code = 1102 // ColumnNotFound represent that a column was not found in the underlying db
MaxRetries Code = 1103 // MaxRetries represent that a db Tx hit max retires allowed
Exception Code = 1104 // Exception represent that an underlying db exception was raised
)

@ -52,6 +52,26 @@ func TestCode_Both_String_Info(t *testing.T) {
c: EmptyFieldMask,
want: EmptyFieldMask,
},
{
name: "PasswordTooShort",
c: PasswordTooShort,
want: PasswordTooShort,
},
{
name: "PasswordUnsupportedConfiguration",
c: PasswordUnsupportedConfiguration,
want: PasswordUnsupportedConfiguration,
},
{
name: "PasswordInvalidConfiguration",
c: PasswordInvalidConfiguration,
want: PasswordInvalidConfiguration,
},
{
name: "PasswordsEqual",
c: PasswordsEqual,
want: PasswordsEqual,
},
{
name: "CheckConstraint",
c: CheckConstraint,
@ -72,6 +92,21 @@ func TestCode_Both_String_Info(t *testing.T) {
c: RecordNotFound,
want: RecordNotFound,
},
{
name: "ColumnNotFound",
c: ColumnNotFound,
want: ColumnNotFound,
},
{
name: "MaxRetries",
c: MaxRetries,
want: MaxRetries,
},
{
name: "Exception",
c: Exception,
want: Exception,
},
{
name: "MultipleRecords",
c: MultipleRecords,

@ -117,8 +117,10 @@ func Convert(e error) *Err {
if e == nil {
return nil
}
var err *Err
if As(e, &err) {
// TODO instead of casting the error here, we should do an As.
// Currently doing an As loses any additional context added by non-refactored packages
// that are still wrapping with stdlib
if err, ok := e.(*Err); ok {
return err
}
var pqError *pq.Error
@ -126,7 +128,7 @@ func Convert(e error) *Err {
if pqError.Code.Class() == "23" { // class of integrity constraint violations
switch pqError.Code {
case "23505": // unique_violation
return E(WithMsg(pqError.Detail), WithWrap(ErrNotUnique)).(*Err)
return E(WithMsg(pqError.Message), WithWrap(ErrNotUnique)).(*Err)
case "23502": // not_null_violation
msg := fmt.Sprintf("%s must not be empty", pqError.Column)
return E(WithMsg(msg), WithWrap(ErrNotNull)).(*Err)
@ -137,8 +139,13 @@ func Convert(e error) *Err {
return E(WithCode(NotSpecificIntegrity), WithMsg(pqError.Message)).(*Err)
}
}
if pqError.Code == "42P01" {
switch pqError.Code {
case "42P01":
return E(WithCode(MissingTable), WithMsg(pqError.Message)).(*Err)
case "42703":
return E(WithCode(ColumnNotFound), WithMsg(pqError.Message)).(*Err)
case "P0001":
return E(WithCode(Exception), WithMsg(pqError.Message)).(*Err)
}
}
// unfortunately, we can't help.

@ -451,7 +451,7 @@ func TestConvertError(t *testing.T) {
e := errors.Convert(err)
require.NotNil(e)
assert.True(errors.Is(e, errors.ErrNotUnique))
assert.Equal("Key (name)=(alice) already exists.: unique constraint violation: integrity violation: error #1002", e.Error())
assert.Equal("db.Exec: duplicate key value violates unique constraint \"test_table_name_key\": unique constraint violation: integrity violation: error #1002", e.Error())
})
t.Run("ErrCodeNotNull", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -463,7 +463,7 @@ func TestConvertError(t *testing.T) {
e := errors.Convert(err)
require.NotNil(e)
assert.True(errors.Is(e, errors.ErrNotNull))
assert.Equal("description must not be empty: not null constraint violated: integrity violation: error #1001", e.Error())
assert.Equal("db.Exec: description must not be empty: not null constraint violated: integrity violation: error #1001", e.Error())
})
t.Run("ErrCodeCheckConstraint", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -475,7 +475,7 @@ func TestConvertError(t *testing.T) {
e := errors.Convert(err)
require.NotNil(e)
assert.True(errors.Is(e, errors.ErrCheckConstraint))
assert.Equal("test_table_five_check constraint failed: check constraint violated: integrity violation: error #1000", e.Error())
assert.Equal("db.Exec: test_table_five_check constraint failed: check constraint violated: integrity violation: error #1000", e.Error())
})
t.Run("MissingTable", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@ -485,6 +485,6 @@ func TestConvertError(t *testing.T) {
e := errors.Convert(err)
require.NotNil(e)
assert.True(errors.Match(errors.T(errors.MissingTable), e))
assert.Equal("relation \"not_a_defined_table\" does not exist: integrity violation: error #1004", e.Error())
assert.Equal("db.Exec: relation \"not_a_defined_table\" does not exist: integrity violation: error #1004", e.Error())
})
}

@ -36,6 +36,22 @@ var errorCodeInfo = map[Code]Info{
Message: "empty field mask",
Kind: Parameter,
},
PasswordTooShort: {
Message: "too short",
Kind: Password,
},
PasswordUnsupportedConfiguration: {
Message: "unable to support the password config type",
Kind: Password,
},
PasswordInvalidConfiguration: {
Message: "invalid parameters in password configuration",
Kind: Password,
},
PasswordsEqual: {
Message: "old and new password are equal",
Kind: Password,
},
CheckConstraint: {
Message: "constraint check failed",
Kind: Integrity,
@ -56,6 +72,10 @@ var errorCodeInfo = map[Code]Info{
Message: "missing table",
Kind: Integrity,
},
ColumnNotFound: {
Message: "column not found",
Kind: Integrity,
},
RecordNotFound: {
Message: "record not found",
Kind: Search,
@ -64,4 +84,12 @@ var errorCodeInfo = map[Code]Info{
Message: "multiple records",
Kind: Search,
},
Exception: {
Message: "db exception",
Kind: Integrity,
},
MaxRetries: {
Message: "too many retries",
Kind: Transaction,
},
}

@ -13,11 +13,8 @@ func IsUniqueError(err error) bool {
return false
}
var domainErr *Err
if errors.As(err, &domainErr) {
if domainErr.Code == NotUnique {
return true
}
if Match(T(NotUnique), err) {
return true
}
var pqError *pq.Error
@ -37,11 +34,8 @@ func IsCheckConstraintError(err error) bool {
return false
}
var domainErr *Err
if errors.As(err, &domainErr) {
if domainErr.Code == CheckConstraint {
return true
}
if Match(T(CheckConstraint), err) {
return true
}
var pqError *pq.Error
@ -61,11 +55,8 @@ func IsNotNullError(err error) bool {
return false
}
var domainErr *Err
if errors.As(err, &domainErr) {
if domainErr.Code == NotNull {
return true
}
if Match(T(NotNull), err) {
return true
}
var pqError *pq.Error
@ -97,11 +88,8 @@ func IsNotFoundError(err error) bool {
return false
}
var domainErr *Err
if errors.As(err, &domainErr) {
if domainErr.Code == RecordNotFound {
return true
}
if Match(T(RecordNotFound), err) {
return true
}
return false

@ -8,13 +8,17 @@ const (
Parameter
Integrity
Search
Password
Transaction
)
func (e Kind) String() string {
return map[Kind]string{
Other: "unknown",
Parameter: "parameter violation",
Integrity: "integrity violation",
Search: "search issue",
Other: "unknown",
Parameter: "parameter violation",
Integrity: "integrity violation",
Search: "search issue",
Password: "password violation",
Transaction: "db transaction issue",
}[e]
}

@ -60,15 +60,15 @@ func (t *Template) Error() string {
return "Template error"
}
// Match the template against the error. The error must be a *Err, or match
// will return false. Matches all non-empty fields of the template against the
// Match the template against the error. The error must be of type *Err, or wrap an error of type *Err,
// otherwise match will return false. Matches all non-empty fields of the template against the
// error.
func Match(t *Template, err error) bool {
if t == nil || err == nil {
return false
}
e, ok := err.(*Err)
if !ok {
var e *Err
if !As(err, &e) {
return false
}

@ -14,11 +14,11 @@ var (
// ErrInvalidFieldMask is returned by update methods if the field mask
// contains unknown fields or fields that cannot be updated.
ErrInvalidFieldMask = E(WithCode(InvalidParameter), WithMsg("invalid field mask"))
ErrInvalidFieldMask = E(WithCode(InvalidFieldMask), WithMsg("invalid field mask"))
// ErrEmptyFieldMask is returned by update methods if the field mask is
// empty.
ErrEmptyFieldMask = E(WithCode(InvalidParameter), WithMsg("empty field mask"))
ErrEmptyFieldMask = E(WithCode(EmptyFieldMask), WithMsg("empty field mask"))
// ErrNotUnique is returned by create and update methods when a write
// to the repository resulted in a unique constraint violation.

@ -545,7 +545,7 @@ func TestRepository_UpdateSet(t *testing.T) {
assert.Equal(db.NoRowsAffected, gotCount2, "row count")
err = db.TestVerifyOplog(t, rw, sB.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
assert.Empty(gotHosts)
})

@ -665,7 +665,7 @@ func TestRepository_UpdateHost(t *testing.T) {
assert.Equal(db.NoRowsAffected, gotCount2, "row count")
err = db.TestVerifyOplog(t, rw, hB.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
t.Run("valid-duplicate-names-diff-Catalogs", func(t *testing.T) {

@ -126,7 +126,7 @@ func Test_GroupMemberCreate(t *testing.T) {
wantDup bool
wantErr bool
wantErrMsg string
wantIsErr error
wantIsErr errors.Code
}{
{
name: "valid-with-org",
@ -166,7 +166,7 @@ func Test_GroupMemberCreate(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: `create: failed: pq: insert or update on table "iam_group_member_user" violates foreign key constraint`,
wantErrMsg: `db.Create: create failed: insert or update on table "iam_group_member_user" violates foreign key constraint`,
},
{
name: "bad-user-id",
@ -180,7 +180,7 @@ func Test_GroupMemberCreate(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: `create: failed: pq: insert or update on table "iam_group_member_user" violates foreign key constraint`,
wantErrMsg: `db.Create: create failed: insert or update on table "iam_group_member_user" violates foreign key constraint`,
},
{
name: "missing-group-id",
@ -196,7 +196,7 @@ func Test_GroupMemberCreate(t *testing.T) {
}(),
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "missing-user-id",
@ -212,7 +212,7 @@ func Test_GroupMemberCreate(t *testing.T) {
}(),
},
wantErr: true,
wantIsErr: errors.ErrInvalidParameter,
wantIsErr: errors.InvalidParameter,
},
{
name: "dup-at-org",
@ -227,7 +227,7 @@ func Test_GroupMemberCreate(t *testing.T) {
},
wantDup: true,
wantErr: true,
wantErrMsg: `create: failed: pq: duplicate key value violates unique constraint "iam_group_member_user_pkey"`,
wantErrMsg: `db.Create: create failed: duplicate key value violates unique constraint "iam_group_member_user_pkey"`,
},
}
@ -245,8 +245,8 @@ func Test_GroupMemberCreate(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Contains(err.Error(), tt.wantErrMsg)
if tt.wantIsErr != nil {
assert.True(errors.Is(err, tt.wantIsErr))
if tt.wantIsErr != 0 {
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
}
return
}
@ -333,7 +333,7 @@ func Test_GroupMemberDelete(t *testing.T) {
found := allocGroupMember()
err = rw.LookupWhere(context.Background(), &found, "group_id = ? and member_id = ?", tt.gm.GetGroupId(), tt.gm.GetMemberId())
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -171,7 +171,7 @@ func Test_GroupCreate(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: vet for write failed: scope is not found",
wantErrMsg: "db.Create: vet for write failed: iam.validateScopeForWrite: scope is not found: search issue: error #1100",
},
}
@ -247,7 +247,7 @@ func Test_GroupUpdate(t *testing.T) {
ScopeId: proj.PublicId,
},
wantErr: true,
wantErrMsg: "update: vet for write failed: not allowed to change a resource's scope",
wantErrMsg: "db.Update: vet for write failed: iam.validateScopeForWrite: not allowed to change a resource's scope: parameter violation: error #100",
},
{
name: "proj-scope-id-not-in-mask",
@ -278,7 +278,7 @@ func Test_GroupUpdate(t *testing.T) {
},
wantErr: true,
wantDup: true,
wantErrMsg: `update: failed: pq: duplicate key value violates unique constraint "iam_group_name_scope_id_key"`,
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_group_name_scope_id_key": unique constraint violation: integrity violation: error #1002`,
},
{
name: "set description null",
@ -427,7 +427,7 @@ func Test_GroupDelete(t *testing.T) {
foundGrp.PublicId = tt.group.GetPublicId()
err = rw.LookupByPublicId(context.Background(), &foundGrp)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -176,7 +176,7 @@ func TestUserRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: failed: pq: insert or update on table \"iam_user_role\" violates foreign key constraint \"iam_user_role_role_id_fkey\"",
wantErrMsg: "db.Create: create failed: insert or update on table \"iam_user_role\" violates foreign key constraint \"iam_user_role_role_id_fkey\"",
},
{
name: "bad-user-id",
@ -190,7 +190,7 @@ func TestUserRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: failed: pq: insert or update on table \"iam_user_role\" violates foreign key constraint \"iam_user_role_principal_id_fkey\"",
wantErrMsg: "db.Create: create failed: insert or update on table \"iam_user_role\" violates foreign key constraint \"iam_user_role_principal_id_fkey\"",
},
{
name: "missing-role-id",
@ -206,7 +206,7 @@ func TestUserRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: vet for write failed: new user role: missing role id invalid parameter",
wantErrMsg: "db.Create: vet for write failed: new user role: missing role id invalid parameter",
wantIsErr: errors.ErrInvalidParameter,
},
{
@ -223,7 +223,7 @@ func TestUserRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: vet for write failed: new user role: missing user id invalid parameter",
wantErrMsg: "db.Create: vet for write failed: new user role: missing user id invalid parameter",
wantIsErr: errors.ErrInvalidParameter,
},
{
@ -239,7 +239,7 @@ func TestUserRole_Create(t *testing.T) {
},
wantDup: true,
wantErr: true,
wantErrMsg: `create: failed: pq: duplicate key value violates unique constraint "iam_user_role_pkey"`,
wantErrMsg: `db.Create: create failed: duplicate key value violates unique constraint "iam_user_role_pkey"`,
},
}
@ -345,7 +345,7 @@ func TestUserRole_Delete(t *testing.T) {
found := allocUserRole()
err = rw.LookupWhere(context.Background(), &found, "role_id = ? and principal_id = ?", tt.role.GetRoleId(), tt.role.GetPrincipalId())
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -539,7 +539,7 @@ func TestGroupRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: failed: pq: insert or update on table \"iam_group_role\" violates foreign key constraint \"iam_group_role_role_id_fkey\"",
wantErrMsg: "db.Create: create failed: insert or update on table \"iam_group_role\" violates foreign key constraint \"iam_group_role_role_id_fkey\"",
},
{
name: "bad-user-id",
@ -553,7 +553,7 @@ func TestGroupRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: failed: pq: insert or update on table \"iam_group_role\" violates foreign key constraint \"iam_group_role_principal_id_fkey\"",
wantErrMsg: "db.Create: create failed: insert or update on table \"iam_group_role\" violates foreign key constraint \"iam_group_role_principal_id_fkey\"",
},
{
name: "missing-role-id",
@ -569,7 +569,7 @@ func TestGroupRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: vet for write failed: new group role: missing role id invalid parameter",
wantErrMsg: "db.Create: vet for write failed: new group role: missing role id invalid parameter",
wantIsErr: errors.ErrInvalidParameter,
},
{
@ -586,7 +586,7 @@ func TestGroupRole_Create(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: vet for write failed: new group role: missing user id invalid parameter",
wantErrMsg: "db.Create: vet for write failed: new group role: missing user id invalid parameter",
wantIsErr: errors.ErrInvalidParameter,
},
{
@ -602,7 +602,7 @@ func TestGroupRole_Create(t *testing.T) {
},
wantDup: true,
wantErr: true,
wantErrMsg: `create: failed: pq: duplicate key value violates unique constraint`,
wantErrMsg: `db.Create: create failed: duplicate key value violates unique constraint`,
},
{
name: "dup-at-proj",
@ -617,7 +617,7 @@ func TestGroupRole_Create(t *testing.T) {
},
wantDup: true,
wantErr: true,
wantErrMsg: `create: failed: pq: duplicate key value violates unique constraint`,
wantErrMsg: `db.Create: create failed: duplicate key value violates unique constraint`,
},
}
@ -728,7 +728,7 @@ func TestGroupRole_Delete(t *testing.T) {
found := allocGroupRole()
err = rw.LookupWhere(context.Background(), &found, "role_id = ? and principal_id = ?", tt.role.GetRoleId(), tt.role.GetPrincipalId())
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -141,7 +141,7 @@ func (r *Repository) LookupGroup(ctx context.Context, withPublicId string, opt .
},
)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil, nil
}
return nil, nil, fmt.Errorf("lookup group: failed %w for %s", err, withPublicId)

@ -106,7 +106,7 @@ func TestRepository_CreateGroup(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create group: error getting metadata for create: unable to get scope for standard metadata: record not found",
wantErrMsg: "create group: error getting metadata for create: unable to get scope for standard metadata: db.LookupWhere: record not found",
wantIsError: errors.ErrInvalidParameter,
},
{
@ -199,7 +199,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
wantRowsUpdate int
wantErr bool
wantErrMsg string
wantIsError error
wantIsError errors.Code
wantDup bool
directUpdate bool
}{
@ -237,8 +237,8 @@ func TestRepository_UpdateGroup(t *testing.T) {
newScopeId: org.PublicId,
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update group: update: lookup after write: record not found",
wantIsError: errors.ErrRecordNotFound,
wantErrMsg: "update group: db.DoTx: db.DoTx: db.Update: db.lookupAfterWrite: db.LookupById: record not found",
wantIsError: errors.RecordNotFound,
},
{
name: "null-name",
@ -275,7 +275,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update group: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "nil-fieldmask",
@ -288,7 +288,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update group: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "read-only-fields",
@ -301,7 +301,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update group: field: CreateTime: invalid field mask",
wantIsError: errors.ErrInvalidFieldMask,
wantIsError: errors.InvalidFieldMask,
},
{
name: "unknown-fields",
@ -314,7 +314,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update group: field: Alice: invalid field mask",
wantIsError: errors.ErrInvalidFieldMask,
wantIsError: errors.InvalidFieldMask,
},
{
name: "no-public-id",
@ -327,7 +327,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
newScopeId: org.PublicId,
wantErr: true,
wantErrMsg: "update group: missing group public id invalid parameter",
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
wantRowsUpdate: 0,
},
{
@ -339,7 +339,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
newScopeId: org.PublicId,
wantErr: true,
wantErrMsg: "update group: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "empty-scope-id-with-name-mask",
@ -376,7 +376,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
wantErr: true,
wantDup: true,
wantErrMsg: " already exists in org " + org.PublicId,
wantIsError: errors.ErrNotUnique,
wantIsError: errors.NotUnique,
},
{
name: "modified-scope",
@ -388,7 +388,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
},
newScopeId: org.PublicId,
wantErr: true,
wantErrMsg: `update: failed: pq: immutable column: iam_group.scope_id`,
wantErrMsg: `db.DoTx: db.Update: immutable column: iam_group.scope_id`,
directUpdate: true,
},
}
@ -429,15 +429,15 @@ func TestRepository_UpdateGroup(t *testing.T) {
}
if tt.wantErr {
assert.Error(err)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
assert.Nil(groupAfterUpdate)
assert.Equal(0, updatedRows)
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, u.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
assert.NoError(err)
@ -519,7 +519,7 @@ func TestRepository_DeleteGroup(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantErrMsg: "delete group: failed record not found:",
wantErrMsg: "delete group: failed db.LookupById: record not found",
},
}
for _, tt := range tests {
@ -532,7 +532,7 @@ func TestRepository_DeleteGroup(t *testing.T) {
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, tt.args.group.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
assert.NoError(err)
@ -984,7 +984,7 @@ func TestRepository_DeleteGroupMembers(t *testing.T) {
}
err = db.TestVerifyOplog(t, rw, tt.args.group.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.Match(errors.T(errors.RecordNotFound), err))
return
}
require.NoError(err)

@ -499,7 +499,7 @@ func TestRepository_DeletePrincipalRoles(t *testing.T) {
}
err = db.TestVerifyOplog(t, rw, tt.args.role.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)

@ -152,7 +152,7 @@ func (r *Repository) LookupRole(ctx context.Context, withPublicId string, opt ..
},
)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil, nil, nil
}
return nil, nil, nil, err

@ -380,7 +380,7 @@ func TestRepository_DeleteRoleGrants(t *testing.T) {
}
err = db.TestVerifyOplog(t, rw, tt.args.role.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)

@ -107,7 +107,7 @@ func TestRepository_CreateRole(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create role: error getting metadata for create: unable to get scope for standard metadata: record not found:",
wantErrMsg: "create role: error getting metadata for create: unable to get scope for standard metadata: db.LookupWhere: record not found",
wantIsError: errors.ErrInvalidParameter,
},
{
@ -201,7 +201,7 @@ func TestRepository_UpdateRole(t *testing.T) {
wantRowsUpdate int
wantErr bool
wantErrMsg string
wantIsError error
wantIsError errors.Code
wantDup bool
}{
{
@ -238,8 +238,8 @@ func TestRepository_UpdateRole(t *testing.T) {
newScopeId: org.PublicId,
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update role: update: lookup after write: record not found:",
wantIsError: errors.ErrRecordNotFound,
wantErrMsg: "update role: db.DoTx: db.DoTx: db.Update: db.lookupAfterWrite: db.LookupById: record not found",
wantIsError: errors.RecordNotFound,
},
{
name: "null-name",
@ -276,7 +276,7 @@ func TestRepository_UpdateRole(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update role: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "nil-fieldmask",
@ -289,7 +289,7 @@ func TestRepository_UpdateRole(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update role: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "read-only-fields",
@ -302,7 +302,7 @@ func TestRepository_UpdateRole(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update role: field: CreateTime: invalid field mask",
wantIsError: errors.ErrInvalidFieldMask,
wantIsError: errors.InvalidFieldMask,
},
{
name: "unknown-fields",
@ -315,7 +315,7 @@ func TestRepository_UpdateRole(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update role: field: Alice: invalid field mask",
wantIsError: errors.ErrInvalidFieldMask,
wantIsError: errors.InvalidFieldMask,
},
{
name: "no-public-id",
@ -328,7 +328,7 @@ func TestRepository_UpdateRole(t *testing.T) {
newScopeId: org.PublicId,
wantErr: true,
wantErrMsg: "update role: missing role public id invalid parameter",
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
wantRowsUpdate: 0,
},
{
@ -340,7 +340,7 @@ func TestRepository_UpdateRole(t *testing.T) {
newScopeId: org.PublicId,
wantErr: true,
wantErrMsg: "update role: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "empty-scope-id-with-name-mask",
@ -377,7 +377,7 @@ func TestRepository_UpdateRole(t *testing.T) {
wantErr: true,
wantDup: true,
wantErrMsg: " already exists in org " + org.PublicId,
wantIsError: errors.ErrNotUnique,
wantIsError: errors.NotUnique,
},
}
for _, tt := range tests {
@ -423,15 +423,15 @@ func TestRepository_UpdateRole(t *testing.T) {
roleAfterUpdate, principals, grants, updatedRows, err := repo.UpdateRole(context.Background(), &updateRole, r.Version, tt.args.fieldMaskPaths, tt.args.opt...)
if tt.wantErr {
assert.Error(err)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
assert.Nil(roleAfterUpdate)
assert.Equal(0, updatedRows)
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, r.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -517,7 +517,7 @@ func TestRepository_DeleteRole(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantErrMsg: "delete role: failed record not found:",
wantErrMsg: "delete role: failed db.LookupById: record not found",
},
}
for _, tt := range tests {
@ -530,7 +530,7 @@ func TestRepository_DeleteRole(t *testing.T) {
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, tt.args.role.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
assert.NoError(err)

@ -392,7 +392,7 @@ func (r *Repository) LookupScope(ctx context.Context, withPublicId string, opt .
scope := allocScope()
scope.PublicId = withPublicId
if err := r.reader.LookupByPublicId(ctx, &scope); err != nil {
if err == errors.ErrRecordNotFound {
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, fmt.Errorf("lookup scope: failed %w fo %s", err, withPublicId)

@ -242,7 +242,7 @@ func TestRepository_update(t *testing.T) {
},
wantUpdatedRows: 0,
wantErr: true,
wantErrMsg: "update: getting update fields failed: fieldMashPaths and setToNullPaths cannot intersect",
wantErrMsg: "db.DoTx: db.Update: getting update fields failed: common.UpdateFields: fieldMashPaths and setToNullPaths cannot intersect: parameter violation: error #100",
},
{
name: "only-field-masks",

@ -166,7 +166,7 @@ func (r *Repository) LookupUser(ctx context.Context, userId string, opt ...Optio
user := allocUser()
user.PublicId = userId
if err := r.reader.LookupByPublicId(ctx, &user); err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil, nil
}
return nil, nil, fmt.Errorf("lookup user: failed %w for %s", err, userId)

@ -59,7 +59,7 @@ func TestRepository_CreateUser(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create user: error getting metadata for create: unable to get scope for standard metadata: record not found:",
wantErrMsg: "create user: error getting metadata for create: unable to get scope for standard metadata: db.LookupWhere: record not found",
},
{
name: "dup-name",
@ -135,7 +135,7 @@ func TestRepository_UpdateUser(t *testing.T) {
wantRowsUpdate int
wantErr bool
wantErrMsg string
wantIsErr error
wantIsErr errors.Code
wantDup bool
directUpdate bool
}{
@ -170,8 +170,8 @@ func TestRepository_UpdateUser(t *testing.T) {
},
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update user: update: lookup after write: record not found:",
wantIsErr: errors.ErrRecordNotFound,
wantErrMsg: "update user: db.DoTx: db.Update: db.lookupAfterWrite: db.LookupById: record not found",
wantIsErr: errors.RecordNotFound,
},
{
name: "null-name",
@ -291,7 +291,7 @@ func TestRepository_UpdateUser(t *testing.T) {
opt: []Option{WithSkipVetForWrite(true)},
},
wantErr: true,
wantErrMsg: `update: failed: pq: immutable column: iam_user.scope_id`,
wantErrMsg: `db.DoTx: db.Update: immutable column: iam_user.scope_id:`,
directUpdate: true,
},
}
@ -339,8 +339,8 @@ func TestRepository_UpdateUser(t *testing.T) {
}
if tt.wantErr {
require.Error(err)
if tt.wantIsErr != nil {
assert.True(errors.Is(err, errors.ErrRecordNotFound))
if tt.wantIsErr != 0 {
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
}
assert.Nil(userAfterUpdate)
assert.Equal(0, updatedRows)
@ -434,7 +434,7 @@ func TestRepository_DeleteUser(t *testing.T) {
},
wantRowsDeleted: 1,
wantErr: true,
wantErrMsg: "delete user: failed record not found:",
wantErrMsg: "delete user: failed db.LookupById: record not found",
},
}
for _, tt := range tests {
@ -567,7 +567,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
wantName string
wantDescription string
wantErr bool
wantErrIs error
wantErrIs errors.Code
wantUser *User
}{
{
@ -590,7 +590,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
withAccountId: newAuthAcctWithoutVivify.PublicId,
},
wantErr: true,
wantErrIs: errors.ErrRecordNotFound,
wantErrIs: errors.RecordNotFound,
},
{
name: "missing auth acct id",
@ -598,7 +598,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
withAccountId: "",
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "existing-auth-account",
@ -627,7 +627,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
withAccountId: id,
},
wantErr: true,
wantErrIs: errors.ErrRecordNotFound,
wantErrIs: errors.RecordNotFound,
},
{
name: "bad-auth-account-id-with-vivify",
@ -638,7 +638,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
},
},
wantErr: true,
wantErrIs: errors.ErrRecordNotFound,
wantErrIs: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -649,8 +649,8 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Nil(got)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error %s", err.Error())
}
if tt.args.withAccountId != "" && tt.args.withAccountId != id {
// need to assert that userid in auth_account is still null
@ -704,7 +704,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
want *User
want1 *authAccount
wantErr bool
wantErrIs error
wantErrIs errors.Code
wantAssoc bool
}{
{
@ -728,7 +728,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "missing-userId",
@ -739,7 +739,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "already-properly-assoc",
@ -763,7 +763,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "assoc-with-diff-user-withDisassociateOption",
@ -776,7 +776,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad-acct-id",
@ -788,7 +788,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrRecordNotFound,
wantErrIs: errors.RecordNotFound,
},
{
name: "bad-user-id-not-associated-account",
@ -820,8 +820,8 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
err := associateUserWithAccounts(context.Background(), kms, rw, rw, tt.args.Ids.user, tt.args.Ids.accts, tt.args.opt...)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error %s", err.Error())
}
return
}
@ -861,7 +861,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
want *User
want1 *authAccount
wantErr bool
wantErrIs error
wantErrIs errors.Code
}{
{
name: "simple",
@ -884,7 +884,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "missing-userId",
@ -895,7 +895,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "already-properly-disassoc",
@ -907,7 +907,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "assoc-with-diff-user",
@ -920,7 +920,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad-acct-id",
@ -932,7 +932,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrRecordNotFound,
wantErrIs: errors.RecordNotFound,
},
{
name: "bad-user-id-not-associated-account",
@ -944,7 +944,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
}(),
},
wantErr: true,
wantErrIs: errors.ErrInvalidParameter,
wantErrIs: errors.InvalidParameter,
},
{
name: "bad-user-id",
@ -966,8 +966,8 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
err := dissociateUserFromAccounts(context.Background(), kms, rw, rw, tt.args.Ids.user, tt.args.Ids.accts, tt.args.opt...)
if tt.wantErr {
require.Error(err)
if tt.wantErrIs != nil {
assert.Truef(errors.Is(err, tt.wantErrIs), "unexpected error %s", err.Error())
if tt.wantErrIs != 0 {
assert.Truef(errors.Match(errors.T(tt.wantErrIs), err), "unexpected error %s", err.Error())
}
return
}

@ -77,16 +77,17 @@ func LookupScope(ctx context.Context, reader db.Reader, resource ResourceWithSco
// validateScopeForWrite will validate that the scope is okay for db write operations
func validateScopeForWrite(ctx context.Context, r db.Reader, resource ResourceWithScope, opType db.OpType, opt ...db.Option) error {
const op = "iam.validateScopeForWrite"
opts := db.GetOpts(opt...)
if opType == db.CreateOp {
if resource.GetScopeId() == "" {
return stderrors.New("error scope id not set for user write")
return errors.New(errors.InvalidParameter, op, "error scope id not set for user write")
}
ps, err := LookupScope(ctx, r, resource)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
return stderrors.New("scope is not found")
if errors.IsNotFoundError(err) {
return errors.New(errors.RecordNotFound, op, "scope is not found")
}
return err
}
@ -97,13 +98,13 @@ func validateScopeForWrite(ctx context.Context, r db.Reader, resource ResourceWi
}
}
if !validScopeType {
return fmt.Errorf("%s not a valid scope type for this resource", ps.Type)
return errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s not a valid scope type for this resource", ps.Type))
}
}
if opType == db.UpdateOp && resource.GetScopeId() != "" {
if contains(opts.WithFieldMaskPaths, "ScopeId") || contains(opts.WithNullPaths, "ScopeId") {
return stderrors.New("not allowed to change a resource's scope")
return errors.New(errors.InvalidParameter, op, "not allowed to change a resource's scope")
}
}
return nil

@ -171,7 +171,7 @@ func Test_RoleCreate(t *testing.T) {
}(),
},
wantErr: true,
wantErrMsg: "create: vet for write failed: scope is not found",
wantErrMsg: "db.Create: vet for write failed: iam.validateScopeForWrite: scope is not found: search issue: error #1100",
},
}
@ -252,7 +252,7 @@ func Test_RoleUpdate(t *testing.T) {
scopeIdOverride: org.PublicId,
},
wantErr: true,
wantErrMsg: "update: vet for write failed: not allowed to change a resource's scope",
wantErrMsg: "db.Update: vet for write failed: iam.validateScopeForWrite: not allowed to change a resource's scope: parameter violation: error #100",
},
{
name: "proj-scope-id-not-in-mask",
@ -283,7 +283,7 @@ func Test_RoleUpdate(t *testing.T) {
},
wantErr: true,
wantDup: true,
wantErrMsg: `update: failed: pq: duplicate key value violates unique constraint "iam_role_name_scope_id_key"`,
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_role_name_scope_id_key": unique constraint violation: integrity violation: error #1002`,
},
{
name: "set description null",
@ -348,7 +348,7 @@ func Test_RoleUpdate(t *testing.T) {
grantScopeId: proj2.PublicId,
},
wantErr: true,
wantErrMsg: "update: failed: pq: invalid to set grant_scope_id to non-same scope_id when role scope type is project",
wantErrMsg: "db.Update: invalid to set grant_scope_id to non-same scope_id when role scope type is project: integrity violation: error #1104",
},
{
name: "set grant scope in org",
@ -369,7 +369,7 @@ func Test_RoleUpdate(t *testing.T) {
grantScopeId: proj2.PublicId,
},
wantErr: true,
wantErrMsg: "update: failed: pq: grant_scope_id is not a child project of the role scope",
wantErrMsg: "db.Update: grant_scope_id is not a child project of the role scope: integrity violation: error #1104",
},
{
name: "set grant scope in global",
@ -380,7 +380,7 @@ func Test_RoleUpdate(t *testing.T) {
grantScopeId: "global",
},
wantErr: true,
wantErrMsg: "update: failed: pq: grant_scope_id is not a child project of the role scope",
wantErrMsg: "db.Update: grant_scope_id is not a child project of the role scope: integrity violation: error #1104",
},
{
name: "set grant scope to parent",
@ -391,7 +391,7 @@ func Test_RoleUpdate(t *testing.T) {
grantScopeId: org2.PublicId,
},
wantErr: true,
wantErrMsg: "update: failed: pq: invalid to set grant_scope_id to non-same scope_id when role scope type is project",
wantErrMsg: "db.Update: invalid to set grant_scope_id to non-same scope_id when role scope type is project: integrity violation: error #1104",
},
}
for _, tt := range tests {
@ -427,7 +427,7 @@ func Test_RoleUpdate(t *testing.T) {
assert.Equal(tt.wantErrMsg, err.Error())
err = db.TestVerifyOplog(t, rw, role.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
require.Error(err)
assert.Contains(err.Error(), "record not found:")
assert.Contains(err.Error(), "record not found")
return
}
require.NoError(err)
@ -473,7 +473,7 @@ func Test_RoleUpdate(t *testing.T) {
updatedRows, err := rw.Update(context.Background(), &updateRole, []string{"ScopeId"}, nil, db.WithSkipVetForWrite(true))
require.Error(err)
assert.Equal(0, updatedRows)
assert.Equal("update: failed: pq: immutable column: iam_role.scope_id", err.Error())
assert.Equal("db.Update: immutable column: iam_role.scope_id: integrity violation: error #1003", err.Error())
})
}
@ -526,7 +526,7 @@ func Test_RoleDelete(t *testing.T) {
foundRole.PublicId = tt.role.GetPublicId()
err = rw.LookupByPublicId(context.Background(), &foundRole)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -123,7 +123,7 @@ func Test_UserCreate(t *testing.T) {
user.PublicId = id
err = w.Create(context.Background(), user)
require.Error(err)
assert.Equal("create: vet for write failed: scope is not found", err.Error())
assert.Equal("db.Create: vet for write failed: iam.validateScopeForWrite: scope is not found: search issue: error #1100", err.Error())
})
}
@ -168,7 +168,7 @@ func Test_UserUpdate(t *testing.T) {
ScopeId: proj.PublicId,
},
wantErr: true,
wantErrMsg: "update: vet for write failed: not allowed to change a resource's scope",
wantErrMsg: "db.Update: vet for write failed: iam.validateScopeForWrite: not allowed to change a resource's scope: parameter violation: error #100",
},
{
name: "proj-scope-id-not-in-mask",
@ -199,7 +199,7 @@ func Test_UserUpdate(t *testing.T) {
},
wantErr: true,
wantDup: true,
wantErrMsg: `update: failed: pq: duplicate key value violates unique constraint "iam_user_name_scope_id_key"`,
wantErrMsg: `db.Update: duplicate key value violates unique constraint "iam_user_name_scope_id_key": unique constraint violation: integrity violation: error #1002`,
},
}
for _, tt := range tests {

@ -141,7 +141,7 @@ func TestDatabaseKey_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -175,7 +175,7 @@ func TestDatabaseKeyVersion_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -141,7 +141,7 @@ func TestOplogKey_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -175,7 +175,7 @@ func TestOplogKeyVersion_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -39,7 +39,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
name string
args args
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid-org",
@ -57,7 +57,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
keyWrapper: rkvWrapper,
},
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "empty-key",
@ -67,7 +67,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
key: []byte(""),
},
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "nil-wrapper",
@ -77,7 +77,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
keyWrapper: nil,
},
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-rkv-wrapper",
@ -87,7 +87,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
keyWrapper: wrapper,
},
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "wrapper-missing-id",
@ -104,7 +104,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
}(),
},
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -114,8 +114,8 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
if tt.wantErr {
assert.Error(err)
assert.Nil(dk)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
return
}
@ -128,7 +128,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, dk.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
assert.NotNil(dv.CreateTime)
foundKeyVersion, err := repo.LookupDatabaseKeyVersion(context.Background(), tt.args.keyWrapper, dv.PrivateId)
@ -138,7 +138,7 @@ func TestRepository_CreateDatabaseKey(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, dv.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -163,7 +163,7 @@ func TestRepository_DeleteDatabaseKey(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -183,7 +183,7 @@ func TestRepository_DeleteDatabaseKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -199,7 +199,7 @@ func TestRepository_DeleteDatabaseKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -209,13 +209,13 @@ func TestRepository_DeleteDatabaseKey(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -223,12 +223,12 @@ func TestRepository_DeleteDatabaseKey(t *testing.T) {
foundKey, err := repo.LookupDatabaseKey(context.Background(), tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -100,7 +100,7 @@ func TestRepository_CreateDatabaseKeyVersion(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, k.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -127,7 +127,7 @@ func TestRepository_DeleteDatabaseKeyVersion(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -147,7 +147,7 @@ func TestRepository_DeleteDatabaseKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -163,7 +163,7 @@ func TestRepository_DeleteDatabaseKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -173,12 +173,12 @@ func TestRepository_DeleteDatabaseKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -186,12 +186,12 @@ func TestRepository_DeleteDatabaseKeyVersion(t *testing.T) {
foundKey, err := repo.LookupDatabaseKeyVersion(context.Background(), wrapper, tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -215,7 +215,7 @@ func TestRepository_LatestDatabaseKeyVersion(t *testing.T) {
keyWrapper wrapping.Wrapper
wantVersion uint32
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "5",
@ -236,14 +236,14 @@ func TestRepository_LatestDatabaseKeyVersion(t *testing.T) {
createCnt: 0,
keyWrapper: rkvWrapper,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
{
name: "nil-wrapper",
createCnt: 5,
keyWrapper: nil,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -260,8 +260,8 @@ func TestRepository_LatestDatabaseKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Nil(got)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
return
}

@ -128,7 +128,7 @@ func TestRepository_CreateOplogKey(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, opk.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
assert.NotNil(opv.CreateTime)
foundKeyVersion, err := repo.LookupOplogKeyVersion(context.Background(), tt.args.keyWrapper, opv.PrivateId)
@ -138,7 +138,7 @@ func TestRepository_CreateOplogKey(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, opv.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -163,7 +163,7 @@ func TestRepository_DeleteOplogKey(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -183,7 +183,7 @@ func TestRepository_DeleteOplogKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -199,7 +199,7 @@ func TestRepository_DeleteOplogKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -209,13 +209,13 @@ func TestRepository_DeleteOplogKey(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -223,12 +223,12 @@ func TestRepository_DeleteOplogKey(t *testing.T) {
foundKey, err := repo.LookupOplogKey(context.Background(), tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -100,7 +100,7 @@ func TestRepository_CreateOplogKeyVersion(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, k.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -127,7 +127,7 @@ func TestRepository_DeleteOplogKeyVersion(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -147,7 +147,7 @@ func TestRepository_DeleteOplogKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -163,7 +163,7 @@ func TestRepository_DeleteOplogKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -173,12 +173,12 @@ func TestRepository_DeleteOplogKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -186,12 +186,12 @@ func TestRepository_DeleteOplogKeyVersion(t *testing.T) {
foundKey, err := repo.LookupOplogKeyVersion(context.Background(), wrapper, tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -215,7 +215,7 @@ func TestRepository_LatestOplogKeyVersion(t *testing.T) {
keyWrapper wrapping.Wrapper
wantVersion uint32
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "5",
@ -236,14 +236,14 @@ func TestRepository_LatestOplogKeyVersion(t *testing.T) {
createCnt: 0,
keyWrapper: rkvWrapper,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
{
name: "nil-wrapper",
createCnt: 5,
keyWrapper: nil,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -260,8 +260,8 @@ func TestRepository_LatestOplogKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Nil(got)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
return
}

@ -106,7 +106,7 @@ func TestRepository_CreateRootKey(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, rk.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
assert.NotNil(kv.CreateTime)
foundKeyVersion, err := repo.LookupRootKeyVersion(context.Background(), tt.args.keyWrapper, kv.PrivateId)
@ -116,7 +116,7 @@ func TestRepository_CreateRootKey(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, kv.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -140,7 +140,7 @@ func TestRepository_DeleteRootKey(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -160,7 +160,7 @@ func TestRepository_DeleteRootKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -176,7 +176,7 @@ func TestRepository_DeleteRootKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -186,13 +186,13 @@ func TestRepository_DeleteRootKey(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -200,12 +200,12 @@ func TestRepository_DeleteRootKey(t *testing.T) {
foundKey, err := repo.LookupRootKey(context.Background(), wrapper, tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -99,7 +99,7 @@ func TestRepository_CreateRootKeyVersion(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, k.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -124,7 +124,7 @@ func TestRepository_DeleteRootKeyVersion(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -147,7 +147,7 @@ func TestRepository_DeleteRootKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -163,7 +163,7 @@ func TestRepository_DeleteRootKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -173,12 +173,12 @@ func TestRepository_DeleteRootKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -186,12 +186,12 @@ func TestRepository_DeleteRootKeyVersion(t *testing.T) {
foundKey, err := repo.LookupRootKeyVersion(context.Background(), wrapper, tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -213,7 +213,7 @@ func TestRepository_LatestRootKeyVersion(t *testing.T) {
keyWrapper wrapping.Wrapper
wantVersion uint32
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "5",
@ -234,14 +234,14 @@ func TestRepository_LatestRootKeyVersion(t *testing.T) {
createCnt: 0,
keyWrapper: wrapper,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
{
name: "nil-wrapper",
createCnt: 5,
keyWrapper: nil,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -258,8 +258,8 @@ func TestRepository_LatestRootKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Nil(got)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
return
}

@ -128,7 +128,7 @@ func TestRepository_CreateSessionKey(t *testing.T) {
// make sure there was no session written
err = db.TestVerifyOplog(t, rw, tk.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
assert.NotNil(tv.CreateTime)
foundKeyVersion, err := repo.LookupSessionKeyVersion(context.Background(), tt.args.keyWrapper, tv.PrivateId)
@ -138,7 +138,7 @@ func TestRepository_CreateSessionKey(t *testing.T) {
// make sure there was no session written
err = db.TestVerifyOplog(t, rw, tv.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -163,7 +163,7 @@ func TestRepository_DeleteSessionKey(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -183,7 +183,7 @@ func TestRepository_DeleteSessionKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -199,7 +199,7 @@ func TestRepository_DeleteSessionKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -209,13 +209,13 @@ func TestRepository_DeleteSessionKey(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
// make sure there was no session written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -223,12 +223,12 @@ func TestRepository_DeleteSessionKey(t *testing.T) {
foundKey, err := repo.LookupSessionKey(context.Background(), tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no session written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -100,7 +100,7 @@ func TestRepository_CreateSessionKeyVersion(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, k.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -127,7 +127,7 @@ func TestRepository_DeleteSessionKeyVersion(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -147,7 +147,7 @@ func TestRepository_DeleteSessionKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -163,7 +163,7 @@ func TestRepository_DeleteSessionKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -173,12 +173,12 @@ func TestRepository_DeleteSessionKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -186,12 +186,12 @@ func TestRepository_DeleteSessionKeyVersion(t *testing.T) {
foundKey, err := repo.LookupSessionKeyVersion(context.Background(), wrapper, tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -215,7 +215,7 @@ func TestRepository_LatestSessionKeyVersion(t *testing.T) {
keyWrapper wrapping.Wrapper
wantVersion uint32
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "5",
@ -236,14 +236,14 @@ func TestRepository_LatestSessionKeyVersion(t *testing.T) {
createCnt: 0,
keyWrapper: rkvWrapper,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
{
name: "nil-wrapper",
createCnt: 5,
keyWrapper: nil,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -260,8 +260,8 @@ func TestRepository_LatestSessionKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Nil(got)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
return
}

@ -128,7 +128,7 @@ func TestRepository_CreateTokenKey(t *testing.T) {
// make sure there was no token written
err = db.TestVerifyOplog(t, rw, tk.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
assert.NotNil(tv.CreateTime)
foundKeyVersion, err := repo.LookupTokenKeyVersion(context.Background(), tt.args.keyWrapper, tv.PrivateId)
@ -138,7 +138,7 @@ func TestRepository_CreateTokenKey(t *testing.T) {
// make sure there was no token written
err = db.TestVerifyOplog(t, rw, tv.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -163,7 +163,7 @@ func TestRepository_DeleteTokenKey(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -183,7 +183,7 @@ func TestRepository_DeleteTokenKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -199,7 +199,7 @@ func TestRepository_DeleteTokenKey(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -209,13 +209,13 @@ func TestRepository_DeleteTokenKey(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
// make sure there was no token written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -223,12 +223,12 @@ func TestRepository_DeleteTokenKey(t *testing.T) {
foundKey, err := repo.LookupTokenKey(context.Background(), tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no token written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -100,7 +100,7 @@ func TestRepository_CreateTokenKeyVersion(t *testing.T) {
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, k.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -127,7 +127,7 @@ func TestRepository_DeleteTokenKeyVersion(t *testing.T) {
args args
wantRowsDeleted int
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "valid",
@ -147,7 +147,7 @@ func TestRepository_DeleteTokenKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
{
name: "not-found",
@ -163,7 +163,7 @@ func TestRepository_DeleteTokenKeyVersion(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
}
for _, tt := range tests {
@ -173,12 +173,12 @@ func TestRepository_DeleteTokenKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Equal(0, deletedRows)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)
@ -186,12 +186,12 @@ func TestRepository_DeleteTokenKeyVersion(t *testing.T) {
foundKey, err := repo.LookupTokenKeyVersion(context.Background(), wrapper, tt.args.key.PrivateId)
assert.Error(err)
assert.Nil(foundKey)
assert.True(errors.Is(err, errors.ErrRecordNotFound))
assert.True(errors.IsNotFoundError(err))
// make sure there was no oplog written
err = db.TestVerifyOplog(t, rw, tt.args.key.PrivateId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -215,7 +215,7 @@ func TestRepository_LatestTokenKeyVersion(t *testing.T) {
keyWrapper wrapping.Wrapper
wantVersion uint32
wantErr bool
wantIsError error
wantIsError errors.Code
}{
{
name: "5",
@ -236,14 +236,14 @@ func TestRepository_LatestTokenKeyVersion(t *testing.T) {
createCnt: 0,
keyWrapper: rkvWrapper,
wantErr: true,
wantIsError: errors.ErrRecordNotFound,
wantIsError: errors.RecordNotFound,
},
{
name: "nil-wrapper",
createCnt: 5,
keyWrapper: nil,
wantErr: true,
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
},
}
for _, tt := range tests {
@ -260,8 +260,8 @@ func TestRepository_LatestTokenKeyVersion(t *testing.T) {
if tt.wantErr {
require.Error(err)
assert.Nil(got)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
return
}

@ -148,7 +148,7 @@ func TestRootKey_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -155,7 +155,7 @@ func TestRootKeyVersion_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -141,7 +141,7 @@ func TestSessionKey_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -175,7 +175,7 @@ func TestSessionKeyVersion_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -142,7 +142,7 @@ func TestTokenKey_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -175,7 +175,7 @@ func TestTokenKeyVersion_Delete(t *testing.T) {
foundKey.PrivateId = tt.key.PrivateId
err = rw.LookupById(context.Background(), &foundKey)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -173,7 +173,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Account, error
}
u, err := repo.LookupAccount(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("Account %q doesn't exist.", id)
}
return nil, err
@ -273,7 +273,7 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
}
rows, err := repo.DeleteAccount(ctx, scopeId, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete account: %w", err)
@ -309,7 +309,7 @@ func (s Service) changePasswordInRepo(ctx context.Context, scopeId, id string, v
out, err := repo.ChangePassword(ctx, scopeId, id, currentPassword, newPassword, version)
if err != nil {
switch {
case errors.Is(err, errors.ErrRecordNotFound):
case errors.IsNotFoundError(err):
return nil, handlers.NotFoundErrorf("Account not found.")
case errors.Is(err, password.ErrTooShort):
return nil, handlers.InvalidArgumentErrorf("Error in provided request.",
@ -334,7 +334,7 @@ func (s Service) setPasswordInRepo(ctx context.Context, scopeId, id string, vers
out, err := repo.SetPassword(ctx, scopeId, id, pw, version)
if err != nil {
switch {
case errors.Is(err, errors.ErrRecordNotFound):
case errors.IsNotFoundError(err):
return nil, handlers.NotFoundErrorf("Account not found.")
case errors.Is(err, password.ErrTooShort):
return nil, handlers.InvalidArgumentErrorf("Error in provided request.",

@ -178,7 +178,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.AuthMethod, er
}
u, err := repo.LookupAuthMethod(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("AuthMethod %q doesn't exist.", id)
}
return nil, err
@ -287,7 +287,7 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
}
rows, err := repo.DeleteAuthMethod(ctx, scopeId, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete auth method: %w", err)

@ -96,7 +96,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.AuthToken, err
}
u, err := repo.LookupAuthToken(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("AuthToken %q doesn't exist.", id)
}
return nil, fmt.Errorf("unable to lookup auth token: %w", err)
@ -114,7 +114,7 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
}
rows, err := repo.DeleteAuthToken(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete user: %w", err)

@ -192,7 +192,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Group, error)
}
g, m, err := repo.LookupGroup(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("Group %q doesn't exist.", id)
}
return nil, fmt.Errorf("unable to get group: %w", err)
@ -268,7 +268,7 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
}
rows, err := repo.DeleteGroup(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete group: %w", err)

@ -244,7 +244,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Role, error) {
}
out, pr, roleGrants, err := repo.LookupRole(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("Role %q doesn't exist.", id)
}
return nil, err
@ -327,7 +327,7 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
}
rows, err := repo.DeleteRole(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete role: %w", err)

@ -99,7 +99,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Session, error
}
sess, _, err := repo.LookupSession(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("Session %q doesn't exist.", id)
}
return nil, err

@ -278,7 +278,7 @@ func (s Service) AuthorizeSession(ctx context.Context, req *pbs.AuthorizeSession
}
t, hostSets, err := repo.LookupTarget(ctx, t.GetPublicId())
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("Target %q not found.", t.GetPublicId())
}
return nil, err
@ -448,7 +448,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Target, error)
}
u, m, err := repo.LookupTarget(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("Target %q doesn't exist.", id)
}
return nil, err
@ -547,7 +547,7 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
}
rows, err := repo.DeleteTarget(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete target: %w", err)

@ -193,7 +193,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (*pb.User, error) {
}
u, accts, err := repo.LookupUser(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, handlers.NotFoundErrorf("User %q doesn't exist.", id)
}
return nil, err
@ -269,7 +269,7 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
}
rows, err := repo.DeleteUser(ctx, id)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return false, nil
}
return false, fmt.Errorf("unable to delete user: %w", err)

@ -150,7 +150,7 @@ func TestConnectionState_Delete(t *testing.T) {
foundState := allocConnectionState()
err = rw.LookupWhere(context.Background(), &foundState, "connection_id = ? and start_time = ?", tt.state.ConnectionId, initialState.StartTime)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -195,7 +195,7 @@ func TestConnection_Delete(t *testing.T) {
foundConnection.PublicId = tt.connection.PublicId
err = rw.LookupById(context.Background(), &foundConnection)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -35,7 +35,7 @@ func (r *Repository) LookupConnection(ctx context.Context, connectionId string,
},
)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil, nil
}
return nil, nil, fmt.Errorf("lookup connection: %w", err)

@ -184,7 +184,7 @@ func TestRepository_DeleteConnection(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantErrMsg: "delete connection: failed record not found:",
wantErrMsg: "delete connection: failed db.LookupById: record not found",
},
}
for _, tt := range tests {
@ -197,7 +197,7 @@ func TestRepository_DeleteConnection(t *testing.T) {
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, tt.args.connection.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
assert.NoError(err)

@ -138,7 +138,7 @@ func (r *Repository) LookupSession(ctx context.Context, sessionId string, opt ..
},
)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil, nil
}
return nil, nil, fmt.Errorf("lookup session: %w", err)

@ -1532,7 +1532,7 @@ func TestRepository_DeleteSession(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantErrMsg: "delete session: failed record not found:",
wantErrMsg: "delete session: failed db.LookupById: record not found",
},
}
for _, tt := range tests {
@ -1545,7 +1545,7 @@ func TestRepository_DeleteSession(t *testing.T) {
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, tt.args.session.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
assert.NoError(err)

@ -213,7 +213,7 @@ func TestSession_Delete(t *testing.T) {
foundSession.PublicId = tt.session.PublicId
err = rw.LookupById(context.Background(), &foundSession)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -148,7 +148,7 @@ func TestState_Delete(t *testing.T) {
foundState := allocState()
err = rw.LookupWhere(context.Background(), &foundState, "session_id = ? and start_time = ?", tt.state.SessionId, initialState.StartTime)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}

@ -124,7 +124,7 @@ func (r *Repository) LookupTarget(ctx context.Context, publicIdOrName string, op
},
)
if err != nil {
if errors.Is(err, errors.ErrRecordNotFound) {
if errors.IsNotFoundError(err) {
return nil, nil, nil
}
return nil, nil, fmt.Errorf("lookup target: %w", err)

@ -182,7 +182,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
wantRowsUpdate int
wantErr bool
wantErrMsg string
wantIsError error
wantIsError errors.Code
wantDup bool
}{
{
@ -219,8 +219,8 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
newScopeId: proj.PublicId,
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update tcp target: update: lookup after write: record not found",
wantIsError: errors.ErrRecordNotFound,
wantErrMsg: "update tcp target: db.DoTx: db.DoTx: db.Update: db.lookupAfterWrite: db.LookupById: record not found",
wantIsError: errors.RecordNotFound,
},
{
name: "null-name",
@ -233,7 +233,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
newName: "null-name" + id,
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update tcp target: update: failed: pq: null value in column ",
wantErrMsg: "update tcp target: db.DoTx: db.DoTx: db.Update: name must not be empty: not null constraint violated",
},
{
name: "null-description",
@ -258,7 +258,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update tcp target: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "nil-fieldmask",
@ -271,7 +271,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update tcp target: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "read-only-fields",
@ -284,7 +284,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update tcp target: field: CreateTime: invalid field mask",
wantIsError: errors.ErrInvalidFieldMask,
wantIsError: errors.InvalidFieldMask,
},
{
name: "unknown-fields",
@ -297,7 +297,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
wantErr: true,
wantRowsUpdate: 0,
wantErrMsg: "update tcp target: field: Alice: invalid field mask",
wantIsError: errors.ErrInvalidFieldMask,
wantIsError: errors.InvalidFieldMask,
},
{
name: "no-public-id",
@ -310,7 +310,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
newScopeId: proj.PublicId,
wantErr: true,
wantErrMsg: "update tcp target: missing target public id invalid parameter",
wantIsError: errors.ErrInvalidParameter,
wantIsError: errors.InvalidParameter,
wantRowsUpdate: 0,
},
{
@ -322,7 +322,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
newScopeId: proj.PublicId,
wantErr: true,
wantErrMsg: "update tcp target: empty field mask",
wantIsError: errors.ErrEmptyFieldMask,
wantIsError: errors.EmptyFieldMask,
},
{
name: "empty-scope-id-with-name-mask",
@ -346,7 +346,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
wantErr: true,
wantDup: true,
wantErrMsg: " already exists in scope " + proj.PublicId,
wantIsError: errors.ErrNotUnique,
wantIsError: errors.NotUnique,
},
}
for _, tt := range tests {
@ -381,15 +381,15 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
targetAfterUpdate, hostSets, updatedRows, err := repo.UpdateTcpTarget(context.Background(), &updateTarget, target.Version, tt.args.fieldMaskPaths, tt.args.opt...)
if tt.wantErr {
assert.Error(err)
if tt.wantIsError != nil {
assert.True(errors.Is(err, tt.wantIsError))
if tt.wantIsError != 0 {
assert.True(errors.Match(errors.T(tt.wantIsError), err))
}
assert.Nil(targetAfterUpdate)
assert.Equal(0, updatedRows)
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, target.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)

@ -373,7 +373,7 @@ func TestRepository_DeleteTarget(t *testing.T) {
},
wantRowsDeleted: 0,
wantErr: true,
wantErrMsg: "delete target: failed record not found:",
wantErrMsg: "delete target: failed db.LookupById: record not found",
},
}
for _, tt := range tests {
@ -386,7 +386,7 @@ func TestRepository_DeleteTarget(t *testing.T) {
assert.Contains(err.Error(), tt.wantErrMsg)
err = db.TestVerifyOplog(t, rw, tt.args.target.GetPublicId(), db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
assert.NoError(err)
@ -694,7 +694,7 @@ func TestRepository_DeleteTargetHosts(t *testing.T) {
err = db.TestVerifyOplog(t, rw, tt.args.target.GetPublicId(), db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second))
assert.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
return
}
require.NoError(err)

@ -138,7 +138,7 @@ func TestTcpTarget_Delete(t *testing.T) {
foundTarget.PublicId = tt.target.PublicId
err = rw.LookupById(context.Background(), &foundTarget)
require.Error(err)
assert.True(errors.Is(errors.ErrRecordNotFound, err))
assert.True(errors.IsNotFoundError(err))
})
}
}
@ -205,7 +205,7 @@ func TestTcpTarget_Update(t *testing.T) {
},
wantErr: true,
wantDup: true,
wantErrMsg: `update: failed: pq: duplicate key value violates unique constraint "target_tcp_scope_id_name_key"`,
wantErrMsg: `db.Update: duplicate key value violates unique constraint "target_tcp_scope_id_name_key": unique constraint violation: integrity violation: error #1002`,
},
{
name: "set description null",
@ -227,7 +227,7 @@ func TestTcpTarget_Update(t *testing.T) {
ScopeId: proj.PublicId,
},
wantErr: true,
wantErrMsg: `update: failed: pq: null value in column "name" violates not-null constraint`,
wantErrMsg: `db.Update: name must not be empty: not null constraint violated: integrity violation: error #1001`,
},
{
name: "set description null",
@ -267,7 +267,7 @@ func TestTcpTarget_Update(t *testing.T) {
assert.Equal(tt.wantErrMsg, err.Error())
err = db.TestVerifyOplog(t, rw, target.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))
require.Error(err)
assert.Contains(err.Error(), "record not found:")
assert.Contains(err.Error(), "record not found")
return
}
require.NoError(err)

Loading…
Cancel
Save