diff --git a/internal/config/ladder_amend.go b/internal/config/ladder_amend.go index 35e085882..f80a0614f 100644 --- a/internal/config/ladder_amend.go +++ b/internal/config/ladder_amend.go @@ -15,6 +15,14 @@ var ( ladderAmountPattern = regexp.MustCompile(`^(0|[1-9]\d{0,13})(\.\d{1,6})?$`) ) +// ladderAmendValidationError keeps the Validate message for the caller while +// matching ErrLadderAmendInvalid, so store callers can map every invalid +// amendment to a client error with errors.Is. +type ladderAmendValidationError struct{ err error } + +func (e ladderAmendValidationError) Error() string { return e.err.Error() } +func (e ladderAmendValidationError) Unwrap() []error { return []error{ErrLadderAmendInvalid, e.err} } + type LadderAmendment struct { ExpectedRevision *int64 `json:"expected_revision"` ScheduledDate time.Time `json:"scheduled_date"` diff --git a/internal/config/store_postgres_ladder_amend.go b/internal/config/store_postgres_ladder_amend.go index 0c71a534b..1995a4f43 100644 --- a/internal/config/store_postgres_ladder_amend.go +++ b/internal/config/store_postgres_ladder_amend.go @@ -24,7 +24,7 @@ func (s *PostgresStore) LadderTrancheScope(ctx context.Context, id string) (acco func (s *PostgresStore) AmendLadderTranche(ctx context.Context, id, accountID, provider, actor string, amendment LadderAmendment) (*LadderAmendmentResult, error) { if err := amendment.Validate(); err != nil { - return nil, err + return nil, ladderAmendValidationError{err} } if actor == "" { return nil, errors.New("ladder amendment actor is required") diff --git a/internal/config/store_postgres_ladder_amend_test.go b/internal/config/store_postgres_ladder_amend_test.go new file mode 100644 index 000000000..d6226b921 --- /dev/null +++ b/internal/config/store_postgres_ladder_amend_test.go @@ -0,0 +1,20 @@ +package config + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestAmendLadderTranche_InvalidAmendmentMatchesErrLadderAmendInvalid(t *testing.T) { + zero := int64(0) + store := &PostgresStore{} // validation fails before the database is used + _, err := store.AmendLadderTranche(context.Background(), "id", "account", "aws", "actor", + LadderAmendment{ExpectedRevision: &zero, ScheduledDate: time.Now(), AmountUSDHr: "0"}) + require.ErrorIs(t, err, ErrLadderAmendInvalid) + assert.Contains(t, err.Error(), "amount_usd_hr must be a positive decimal") + assert.NotContains(t, err.Error(), "per-run cap") +}