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