feat: add SliceValidationError
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
912d39158f
commit
60d6dc1423
|
@ -6,9 +6,8 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrNothingToUpdate = errors.New("nothing to update")
|
||||
ErrUnsupportedSortBy = errors.New("unsupported sort by")
|
||||
ErrUnsupportedSortDirection = errors.New("unsupported sort direction")
|
||||
ErrNothingToUpdate = errors.New("nothing to update")
|
||||
ErrUnsupportedSortBy = errors.New("unsupported sort by")
|
||||
)
|
||||
|
||||
type ErrorCode uint8
|
||||
|
@ -34,6 +33,7 @@ func (e ErrorCode) String() string {
|
|||
|
||||
type Error interface {
|
||||
error
|
||||
// UserError is a message that is returned to a user in, for example, an http response.
|
||||
UserError() string
|
||||
Code() ErrorCode
|
||||
}
|
||||
|
@ -59,6 +59,28 @@ func (e ValidationError) Unwrap() error {
|
|||
return e.Err
|
||||
}
|
||||
|
||||
type SliceValidationError struct {
|
||||
Field string
|
||||
Index int
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e SliceValidationError) Error() string {
|
||||
return fmt.Sprintf("%s[%d]: %s", e.Field, e.Index, e.Err)
|
||||
}
|
||||
|
||||
func (e SliceValidationError) UserError() string {
|
||||
return e.Error()
|
||||
}
|
||||
|
||||
func (e SliceValidationError) Code() ErrorCode {
|
||||
return ErrorCodeValidationError
|
||||
}
|
||||
|
||||
func (e SliceValidationError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type MaxError struct {
|
||||
Max int
|
||||
}
|
||||
|
|
|
@ -33,6 +33,23 @@ func TestValidationError(t *testing.T) {
|
|||
assert.Equal(t, domain.ErrorCodeValidationError, err.Code())
|
||||
}
|
||||
|
||||
func TestSliceValidationError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
err := domain.SliceValidationError{
|
||||
Field: "test",
|
||||
Index: 15,
|
||||
Err: domain.MinError{
|
||||
Min: 25,
|
||||
},
|
||||
}
|
||||
var _ domain.Error = err
|
||||
assert.Equal(t, fmt.Sprintf("%s[%d]: %s", err.Field, err.Index, err.Err.Error()), err.Error())
|
||||
assert.Equal(t, err.Error(), err.UserError())
|
||||
assert.ErrorIs(t, err, err.Err)
|
||||
assert.Equal(t, domain.ErrorCodeValidationError, err.Code())
|
||||
}
|
||||
|
||||
func TestMinError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
package domain
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnsupportedSortDirection = errors.New("unsupported sort direction")
|
||||
)
|
||||
|
||||
type SortDirection uint8
|
||||
|
||||
const (
|
||||
|
|
|
@ -11,6 +11,10 @@ import (
|
|||
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
||||
)
|
||||
|
||||
const (
|
||||
sortKey = "sort"
|
||||
)
|
||||
|
||||
type queryParams[Sort any] struct {
|
||||
values url.Values
|
||||
newSort func(by string, direction string) (Sort, error)
|
||||
|
@ -85,7 +89,7 @@ func (q queryParams[Sort]) sort() ([]Sort, error) {
|
|||
return nil, errors.New("newSort is nil, can't proceed")
|
||||
}
|
||||
|
||||
vals := q.values["sort"]
|
||||
vals := q.values[sortKey]
|
||||
if len(vals) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -94,16 +98,18 @@ func (q queryParams[Sort]) sort() ([]Sort, error) {
|
|||
for i, v := range vals {
|
||||
index := strings.IndexByte(v, ':')
|
||||
if index == -1 {
|
||||
return nil, domain.ValidationError{
|
||||
Field: fmt.Sprintf("sort[%d]", i),
|
||||
return nil, domain.SliceValidationError{
|
||||
Field: sortKey,
|
||||
Index: i,
|
||||
Err: fmt.Errorf("parsing \"%s\": invalid syntax, expected field:direction", v),
|
||||
}
|
||||
}
|
||||
|
||||
s, err := q.newSort(v[:index], v[index+1:])
|
||||
if err != nil {
|
||||
return nil, domain.ValidationError{
|
||||
Field: fmt.Sprintf("sort[%d]", i),
|
||||
return nil, domain.SliceValidationError{
|
||||
Field: sortKey,
|
||||
Index: i,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue
Block a user