Return error if db.JSON decode hook gets an invalid type
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Elara 2023-01-01 19:28:16 -08:00
parent 8a1d0f4f54
commit 43baf8024a
1 changed files with 18 additions and 3 deletions

View File

@ -33,7 +33,7 @@ import (
"mvdan.cc/sh/v3/syntax" "mvdan.cc/sh/v3/syntax"
) )
var ErrInvalidType = errors.New("val must be a pointer to a struct") var ErrNotPointerToStruct = errors.New("val must be a pointer to a struct")
type VarNotFoundError struct { type VarNotFoundError struct {
name string name string
@ -43,6 +43,16 @@ func (nfe VarNotFoundError) Error() string {
return "required variable '" + nfe.name + "' could not be found" return "required variable '" + nfe.name + "' could not be found"
} }
type InvalidTypeError struct {
name string
vartype string
exptype string
}
func (ite InvalidTypeError) Error() string {
return "variable '" + ite.name + "' is of type " + ite.vartype + ", but " + ite.exptype + " is expected"
}
// Decoder provides methods for decoding variable values // Decoder provides methods for decoding variable values
type Decoder struct { type Decoder struct {
info *distro.OSRelease info *distro.OSRelease
@ -70,6 +80,11 @@ func (d *Decoder) DecodeVar(name string, val any) error {
WeaklyTypedInput: true, WeaklyTypedInput: true,
DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) { DecodeHook: mapstructure.DecodeHookFuncValue(func(from, to reflect.Value) (interface{}, error) {
if strings.Contains(to.Type().String(), "db.JSON") { if strings.Contains(to.Type().String(), "db.JSON") {
valType := to.FieldByName("Val").Type()
if !from.Type().AssignableTo(valType) {
return nil, InvalidTypeError{name, from.Type().String(), valType.String()}
}
to.FieldByName("Val").Set(from) to.FieldByName("Val").Set(from)
return to, nil return to, nil
} }
@ -97,11 +112,11 @@ func (d *Decoder) DecodeVar(name string, val any) error {
func (d *Decoder) DecodeVars(val any) error { func (d *Decoder) DecodeVars(val any) error {
valKind := reflect.TypeOf(val).Kind() valKind := reflect.TypeOf(val).Kind()
if valKind != reflect.Pointer { if valKind != reflect.Pointer {
return ErrInvalidType return ErrNotPointerToStruct
} else { } else {
elemKind := reflect.TypeOf(val).Elem().Kind() elemKind := reflect.TypeOf(val).Elem().Kind()
if elemKind != reflect.Struct { if elemKind != reflect.Struct {
return ErrInvalidType return ErrNotPointerToStruct
} }
} }