unexport dynfunc errors
This commit is contained in:
parent
df56496a16
commit
90472b8bf7
|
@ -3,49 +3,48 @@ package dynfunc
|
|||
// cerr allows you to create constant "const" error with type boxing.
|
||||
type cerr string
|
||||
|
||||
// Error implements the error builtin interface.
|
||||
func (err cerr) Error() string {
|
||||
return string(err)
|
||||
}
|
||||
|
||||
// ErrHandlerNotFunc - handler is not a func
|
||||
const ErrHandlerNotFunc = cerr("handler must be a func")
|
||||
// errHandlerNotFunc - handler is not a func
|
||||
const errHandlerNotFunc = cerr("handler must be a func")
|
||||
|
||||
// ErrNoServiceForHandler - no service matching this handler
|
||||
const ErrNoServiceForHandler = cerr("no service found for this handler")
|
||||
// errNoServiceForHandler - no service matching this handler
|
||||
const errNoServiceForHandler = cerr("no service found for this handler")
|
||||
|
||||
// ErrMissingHandlerArgumentParam - missing params arguments for handler
|
||||
const ErrMissingHandlerArgumentParam = cerr("missing handler argument : parameter struct")
|
||||
// errMissingHandlerArgumentParam - missing params arguments for handler
|
||||
const errMissingHandlerArgumentParam = cerr("missing handler argument : parameter struct")
|
||||
|
||||
// ErrUnexpectedInput - input argument is not expected
|
||||
const ErrUnexpectedInput = cerr("unexpected input struct")
|
||||
// errUnexpectedInput - input argument is not expected
|
||||
const errUnexpectedInput = cerr("unexpected input struct")
|
||||
|
||||
// ErrMissingHandlerOutput - missing output for handler
|
||||
const ErrMissingHandlerOutput = cerr("handler must have at least 1 output")
|
||||
// errMissingHandlerOutput - missing output for handler
|
||||
const errMissingHandlerOutput = cerr("handler must have at least 1 output")
|
||||
|
||||
// ErrMissingHandlerOutputError - missing error output for handler
|
||||
const ErrMissingHandlerOutputError = cerr("handler must have its last output of type api.Error")
|
||||
// errMissingHandlerOutputError - missing error output for handler
|
||||
const errMissingHandlerOutputError = cerr("handler must have its last output of type api.Error")
|
||||
|
||||
// ErrMissingRequestArgument - missing request argument for handler
|
||||
const ErrMissingRequestArgument = cerr("handler first argument must be of type api.Request")
|
||||
// errMissingRequestArgument - missing request argument for handler
|
||||
const errMissingRequestArgument = cerr("handler first argument must be of type api.Request")
|
||||
|
||||
// ErrMissingParamArgument - missing parameters argument for handler
|
||||
const ErrMissingParamArgument = cerr("handler second argument must be a struct")
|
||||
// errMissingParamArgument - missing parameters argument for handler
|
||||
const errMissingParamArgument = cerr("handler second argument must be a struct")
|
||||
|
||||
// ErrUnexportedName - argument is unexported in struct
|
||||
const ErrUnexportedName = cerr("unexported name")
|
||||
// errUnexportedName - argument is unexported in struct
|
||||
const errUnexportedName = cerr("unexported name")
|
||||
|
||||
// ErrMissingParamOutput - missing output argument for handler
|
||||
const ErrMissingParamOutput = cerr("handler first output must be a *struct")
|
||||
// errMissingParamOutput - missing output argument for handler
|
||||
const errMissingParamOutput = cerr("handler first output must be a *struct")
|
||||
|
||||
// ErrMissingParamFromConfig - missing a parameter in handler struct
|
||||
const ErrMissingParamFromConfig = cerr("missing a parameter from configuration")
|
||||
// errMissingParamFromConfig - missing a parameter in handler struct
|
||||
const errMissingParamFromConfig = cerr("missing a parameter from configuration")
|
||||
|
||||
// ErrMissingOutputFromConfig - missing a parameter in handler struct
|
||||
const ErrMissingOutputFromConfig = cerr("missing a parameter from configuration")
|
||||
// errMissingOutputFromConfig - missing a parameter in handler struct
|
||||
const errMissingOutputFromConfig = cerr("missing a parameter from configuration")
|
||||
|
||||
// ErrWrongParamTypeFromConfig - a configuration parameter type is invalid in the handler param struct
|
||||
const ErrWrongParamTypeFromConfig = cerr("invalid struct field type")
|
||||
// errWrongParamTypeFromConfig - a configuration parameter type is invalid in the handler param struct
|
||||
const errWrongParamTypeFromConfig = cerr("invalid struct field type")
|
||||
|
||||
// ErrMissingHandlerErrorOutput - missing handler output error
|
||||
const ErrMissingHandlerErrorOutput = cerr("last output must be of type api.Error")
|
||||
// errMissingHandlerErrorOutput - missing handler output error
|
||||
const errMissingHandlerErrorOutput = cerr("last output must be of type api.Error")
|
||||
|
|
|
@ -32,7 +32,7 @@ func Build(fn interface{}, service config.Service) (*Handler, error) {
|
|||
fnv := reflect.ValueOf(fn)
|
||||
|
||||
if fnv.Type().Kind() != reflect.Func {
|
||||
return nil, ErrHandlerNotFunc
|
||||
return nil, errHandlerNotFunc
|
||||
}
|
||||
|
||||
if err := h.spec.checkInput(fnv); err != nil {
|
||||
|
|
|
@ -50,34 +50,34 @@ func (s spec) checkInput(fnv reflect.Value) error {
|
|||
// no input -> ok
|
||||
if len(s.Input) == 0 {
|
||||
if fnt.NumIn() > 0 {
|
||||
return ErrUnexpectedInput
|
||||
return errUnexpectedInput
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if fnt.NumIn() != 1 {
|
||||
return ErrMissingHandlerArgumentParam
|
||||
return errMissingHandlerArgumentParam
|
||||
}
|
||||
|
||||
// arg must be a struct
|
||||
structArg := fnt.In(0)
|
||||
if structArg.Kind() != reflect.Struct {
|
||||
return ErrMissingParamArgument
|
||||
return errMissingParamArgument
|
||||
}
|
||||
|
||||
// check for invalid param
|
||||
for name, ptype := range s.Input {
|
||||
if name[0] == strings.ToLower(name)[0] {
|
||||
return fmt.Errorf("%s: %w", name, ErrUnexportedName)
|
||||
return fmt.Errorf("%s: %w", name, errUnexportedName)
|
||||
}
|
||||
|
||||
field, exists := structArg.FieldByName(name)
|
||||
if !exists {
|
||||
return fmt.Errorf("%s: %w", name, ErrMissingParamFromConfig)
|
||||
return fmt.Errorf("%s: %w", name, errMissingParamFromConfig)
|
||||
}
|
||||
|
||||
if !ptype.AssignableTo(field.Type) {
|
||||
return fmt.Errorf("%s: %w (%s instead of %s)", name, ErrWrongParamTypeFromConfig, field.Type, ptype)
|
||||
return fmt.Errorf("%s: %w (%s instead of %s)", name, errWrongParamTypeFromConfig, field.Type, ptype)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,13 +88,13 @@ func (s spec) checkInput(fnv reflect.Value) error {
|
|||
func (s spec) checkOutput(fnv reflect.Value) error {
|
||||
fnt := fnv.Type()
|
||||
if fnt.NumOut() < 1 {
|
||||
return ErrMissingHandlerOutput
|
||||
return errMissingHandlerOutput
|
||||
}
|
||||
|
||||
// last output must be api.Error
|
||||
errOutput := fnt.Out(fnt.NumOut() - 1)
|
||||
if !errOutput.AssignableTo(reflect.TypeOf(api.ErrorUnknown)) {
|
||||
return ErrMissingHandlerErrorOutput
|
||||
return errMissingHandlerErrorOutput
|
||||
}
|
||||
|
||||
// no output -> ok
|
||||
|
@ -103,29 +103,29 @@ func (s spec) checkOutput(fnv reflect.Value) error {
|
|||
}
|
||||
|
||||
if fnt.NumOut() != 2 {
|
||||
return ErrMissingParamOutput
|
||||
return errMissingParamOutput
|
||||
}
|
||||
|
||||
// fail if first output is not a pointer to struct
|
||||
structOutputPtr := fnt.Out(0)
|
||||
if structOutputPtr.Kind() != reflect.Ptr {
|
||||
return ErrMissingParamOutput
|
||||
return errMissingParamOutput
|
||||
}
|
||||
|
||||
structOutput := structOutputPtr.Elem()
|
||||
if structOutput.Kind() != reflect.Struct {
|
||||
return ErrMissingParamOutput
|
||||
return errMissingParamOutput
|
||||
}
|
||||
|
||||
// fail on invalid output
|
||||
for name, ptype := range s.Output {
|
||||
if name[0] == strings.ToLower(name)[0] {
|
||||
return fmt.Errorf("%s: %w", name, ErrUnexportedName)
|
||||
return fmt.Errorf("%s: %w", name, errUnexportedName)
|
||||
}
|
||||
|
||||
field, exists := structOutput.FieldByName(name)
|
||||
if !exists {
|
||||
return fmt.Errorf("%s: %w", name, ErrMissingOutputFromConfig)
|
||||
return fmt.Errorf("%s: %w", name, errMissingOutputFromConfig)
|
||||
}
|
||||
|
||||
// ignore types evalutating to nil
|
||||
|
@ -134,7 +134,7 @@ func (s spec) checkOutput(fnv reflect.Value) error {
|
|||
}
|
||||
|
||||
if !field.Type.ConvertibleTo(ptype) {
|
||||
return fmt.Errorf("%s: %w (%s instead of %s)", name, ErrWrongParamTypeFromConfig, field.Type, ptype)
|
||||
return fmt.Errorf("%s: %w (%s instead of %s)", name, errWrongParamTypeFromConfig, field.Type, ptype)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestInputCheck(t *testing.T) {
|
|||
{
|
||||
Input: map[string]reflect.Type{},
|
||||
Fn: func(int, string) {},
|
||||
Err: ErrUnexpectedInput,
|
||||
Err: errUnexpectedInput,
|
||||
},
|
||||
// missing input struct in func
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ func TestInputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() {},
|
||||
Err: ErrMissingHandlerArgumentParam,
|
||||
Err: errMissingHandlerArgumentParam,
|
||||
},
|
||||
// input not a struct
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ func TestInputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func(int) {},
|
||||
Err: ErrMissingParamArgument,
|
||||
Err: errMissingParamArgument,
|
||||
},
|
||||
// unexported param name
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ func TestInputCheck(t *testing.T) {
|
|||
"test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func(struct{}) {},
|
||||
Err: ErrUnexportedName,
|
||||
Err: errUnexportedName,
|
||||
},
|
||||
// input field missing
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ func TestInputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func(struct{}) {},
|
||||
Err: ErrMissingParamFromConfig,
|
||||
Err: errMissingParamFromConfig,
|
||||
},
|
||||
// input field invalid type
|
||||
{
|
||||
|
@ -65,7 +65,7 @@ func TestInputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func(struct{ Test1 string }) {},
|
||||
Err: ErrWrongParamTypeFromConfig,
|
||||
Err: errWrongParamTypeFromConfig,
|
||||
},
|
||||
// input field valid type
|
||||
{
|
||||
|
@ -115,13 +115,13 @@ func TestOutputCheck(t *testing.T) {
|
|||
{
|
||||
Output: map[string]reflect.Type{},
|
||||
Fn: func() {},
|
||||
Err: ErrMissingHandlerOutput,
|
||||
Err: errMissingHandlerOutput,
|
||||
},
|
||||
// no input -> with last type not api.Error
|
||||
{
|
||||
Output: map[string]reflect.Type{},
|
||||
Fn: func() bool { return true },
|
||||
Err: ErrMissingHandlerErrorOutput,
|
||||
Err: errMissingHandlerErrorOutput,
|
||||
},
|
||||
// no input -> with api.Error
|
||||
{
|
||||
|
@ -141,7 +141,7 @@ func TestOutputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() api.Error { return api.ErrorSuccess },
|
||||
Err: ErrMissingParamOutput,
|
||||
Err: errMissingParamOutput,
|
||||
},
|
||||
// output not a pointer
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ func TestOutputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() (int, api.Error) { return 0, api.ErrorSuccess },
|
||||
Err: ErrMissingParamOutput,
|
||||
Err: errMissingParamOutput,
|
||||
},
|
||||
// output not a pointer to struct
|
||||
{
|
||||
|
@ -157,7 +157,7 @@ func TestOutputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() (*int, api.Error) { return nil, api.ErrorSuccess },
|
||||
Err: ErrMissingParamOutput,
|
||||
Err: errMissingParamOutput,
|
||||
},
|
||||
// unexported param name
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ func TestOutputCheck(t *testing.T) {
|
|||
"test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() (*struct{}, api.Error) { return nil, api.ErrorSuccess },
|
||||
Err: ErrUnexportedName,
|
||||
Err: errUnexportedName,
|
||||
},
|
||||
// output field missing
|
||||
{
|
||||
|
@ -173,7 +173,7 @@ func TestOutputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() (*struct{}, api.Error) { return nil, api.ErrorSuccess },
|
||||
Err: ErrMissingParamFromConfig,
|
||||
Err: errMissingParamFromConfig,
|
||||
},
|
||||
// output field invalid type
|
||||
{
|
||||
|
@ -181,7 +181,7 @@ func TestOutputCheck(t *testing.T) {
|
|||
"Test1": reflect.TypeOf(int(0)),
|
||||
},
|
||||
Fn: func() (*struct{ Test1 string }, api.Error) { return nil, api.ErrorSuccess },
|
||||
Err: ErrWrongParamTypeFromConfig,
|
||||
Err: errWrongParamTypeFromConfig,
|
||||
},
|
||||
// output field valid type
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue