From 8c122e9ddfddcff21bdc6cdcf6200374e13a6d7c Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sun, 20 Jun 2021 21:52:11 +0200 Subject: [PATCH] feat: export dynfunc errors --- internal/dynfunc/errors.go | 64 +++++++++++++++--------------- internal/dynfunc/handler.go | 2 +- internal/dynfunc/signature.go | 30 +++++++------- internal/dynfunc/signature_test.go | 40 +++++++++---------- 4 files changed, 69 insertions(+), 67 deletions(-) diff --git a/internal/dynfunc/errors.go b/internal/dynfunc/errors.go index 903e5f0..1fe3932 100644 --- a/internal/dynfunc/errors.go +++ b/internal/dynfunc/errors.go @@ -1,50 +1,52 @@ package dynfunc -// cerr allows you to create constant "const" error with type boxing. -type cerr string +// Err allows you to create constant "const" error with type boxing. +type Err string -func (err cerr) Error() string { +func (err Err) Error() string { return string(err) } -// errHandlerNotFunc - handler is not a func -const errHandlerNotFunc = cerr("handler must be a func") +const ( + // ErrHandlerNotFunc - handler is not a func + ErrHandlerNotFunc = Err("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 + ErrNoServiceForHandler = Err("no service found for this handler") -// errMissingHandlerArgumentParam - missing params arguments for handler -const errMissingHandlerContextArgument = cerr("missing handler first argument of type context.Context") + // errMissingHandlerArgumentParam - missing params arguments for handler + ErrMissingHandlerContextArgument = Err("missing handler first argument of type context.Context") -// errMissingHandlerInputArgument - missing params arguments for handler -const errMissingHandlerInputArgument = cerr("missing handler argument: input struct") + // ErrMissingHandlerInputArgument - missing params arguments for handler + ErrMissingHandlerInputArgument = Err("missing handler argument: input struct") -// errUnexpectedInput - input argument is not expected -const errUnexpectedInput = cerr("unexpected input struct") + // ErrUnexpectedInput - input argument is not expected + ErrUnexpectedInput = Err("unexpected input struct") -// errMissingHandlerOutputArgument - missing output for handler -const errMissingHandlerOutputArgument = cerr("missing handler first output argument: output struct") + // ErrMissingHandlerOutputArgument - missing output for handler + ErrMissingHandlerOutputArgument = Err("missing handler first output argument: output struct") -// errMissingHandlerOutputError - missing error output for handler -const errMissingHandlerOutputError = cerr("missing handler last output argument of type api.Err") + // ErrMissingHandlerOutputError - missing error output for handler + ErrMissingHandlerOutputError = Err("missing handler last output argument of type api.Err") -// errMissingRequestArgument - missing request argument for handler -const errMissingRequestArgument = cerr("handler first argument must be of type api.Request") + // ErrMissingRequestArgument - missing request argument for handler + ErrMissingRequestArgument = Err("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 + ErrMissingParamArgument = Err("handler second argument must be a struct") -// errUnexportedName - argument is unexported in struct -const errUnexportedName = cerr("unexported name") + // ErrUnexportedName - argument is unexported in struct + ErrUnexportedName = Err("unexported name") -// errWrongOutputArgumentType - wrong type for output first argument -const errWrongOutputArgumentType = cerr("handler first output argument must be a *struct") + // ErrWrongOutputArgumentType - wrong type for output first argument + ErrWrongOutputArgumentType = Err("handler first output argument must be a *struct") -// errMissingConfigArgument - missing an input/output argument in handler struct -const errMissingConfigArgument = cerr("missing an argument from the configuration") + // ErrMissingConfigArgument - missing an input/output argument in handler struct + ErrMissingConfigArgument = Err("missing an argument from the 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 + ErrWrongParamTypeFromConfig = Err("invalid struct field type") -// errMissingHandlerErrorArgument - missing handler output error -const errMissingHandlerErrorArgument = cerr("last output must be of type api.Err") + // ErrMissingHandlerErrorArgument - missing handler output error + ErrMissingHandlerErrorArgument = Err("last output must be of type api.Err") +) diff --git a/internal/dynfunc/handler.go b/internal/dynfunc/handler.go index 395d485..b2f109e 100644 --- a/internal/dynfunc/handler.go +++ b/internal/dynfunc/handler.go @@ -38,7 +38,7 @@ func Build(fn interface{}, service config.Service) (*Handler, error) { ) if fnType.Kind() != reflect.Func { - return nil, errHandlerNotFunc + return nil, ErrHandlerNotFunc } if err := h.signature.ValidateInput(fnType); err != nil { return nil, fmt.Errorf("input: %w", err) diff --git a/internal/dynfunc/signature.go b/internal/dynfunc/signature.go index d5c30aa..6875174 100644 --- a/internal/dynfunc/signature.go +++ b/internal/dynfunc/signature.go @@ -53,7 +53,7 @@ func (s *Signature) ValidateInput(handlerType reflect.Type) error { // missing or invalid first arg: context.Context if handlerType.NumIn() < 1 { - return errMissingHandlerContextArgument + return ErrMissingHandlerContextArgument } firstArgType := handlerType.In(0) @@ -65,35 +65,35 @@ func (s *Signature) ValidateInput(handlerType reflect.Type) error { if len(s.Input) == 0 { // input struct provided if handlerType.NumIn() > 1 { - return errUnexpectedInput + return ErrUnexpectedInput } return nil } // too much arguments if handlerType.NumIn() > 2 { - return errMissingHandlerInputArgument + return ErrMissingHandlerInputArgument } // arg must be a struct inStruct := handlerType.In(1) if inStruct.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 := inStruct.FieldByName(name) if !exists { - return fmt.Errorf("%s: %w", name, errMissingConfigArgument) + return fmt.Errorf("%s: %w", name, ErrMissingConfigArgument) } 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) } } @@ -105,13 +105,13 @@ func (s Signature) ValidateOutput(handlerType reflect.Type) error { errType := reflect.TypeOf(api.ErrUnknown) if handlerType.NumOut() < 1 { - return errMissingHandlerErrorArgument + return ErrMissingHandlerErrorArgument } // last output must be api.Err lastArgType := handlerType.Out(handlerType.NumOut() - 1) if !lastArgType.AssignableTo(errType) { - return errMissingHandlerErrorArgument + return ErrMissingHandlerErrorArgument } // no output -> ok @@ -120,29 +120,29 @@ func (s Signature) ValidateOutput(handlerType reflect.Type) error { } if handlerType.NumOut() < 2 { - return errMissingHandlerOutputArgument + return ErrMissingHandlerOutputArgument } // fail if first output is not a pointer to struct outStructPtr := handlerType.Out(0) if outStructPtr.Kind() != reflect.Ptr { - return errWrongOutputArgumentType + return ErrWrongOutputArgumentType } outStruct := outStructPtr.Elem() if outStruct.Kind() != reflect.Struct { - return errWrongOutputArgumentType + return ErrWrongOutputArgumentType } // 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 := outStruct.FieldByName(name) if !exists { - return fmt.Errorf("%s: %w", name, errMissingConfigArgument) + return fmt.Errorf("%s: %w", name, ErrMissingConfigArgument) } // ignore types evalutating to nil @@ -151,7 +151,7 @@ func (s Signature) ValidateOutput(handlerType reflect.Type) 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) } } diff --git a/internal/dynfunc/signature_test.go b/internal/dynfunc/signature_test.go index 3554abf..8eff40d 100644 --- a/internal/dynfunc/signature_test.go +++ b/internal/dynfunc/signature_test.go @@ -30,14 +30,14 @@ func TestInputCheck(t *testing.T) { Input: map[string]reflect.Type{}, Fn: func(context.Context, int) {}, FnCtx: func(context.Context, int) {}, - Err: errUnexpectedInput, + Err: ErrUnexpectedInput, }, { Name: "no input 2 given", Input: map[string]reflect.Type{}, Fn: func(context.Context, int, string) {}, FnCtx: func(context.Context, int, string) {}, - Err: errUnexpectedInput, + Err: ErrUnexpectedInput, }, { Name: "1 input 0 given", @@ -46,7 +46,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context) {}, FnCtx: func(context.Context) {}, - Err: errMissingHandlerInputArgument, + Err: ErrMissingHandlerInputArgument, }, { Name: "1 input non-struct given", @@ -55,7 +55,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, int) {}, FnCtx: func(context.Context, int) {}, - Err: errMissingParamArgument, + Err: ErrMissingParamArgument, }, { Name: "unexported input", @@ -64,7 +64,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, struct{}) {}, FnCtx: func(context.Context, struct{}) {}, - Err: errUnexportedName, + Err: ErrUnexportedName, }, { Name: "1 input empty struct given", @@ -73,7 +73,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, struct{}) {}, FnCtx: func(context.Context, struct{}) {}, - Err: errMissingConfigArgument, + Err: ErrMissingConfigArgument, }, { Name: "1 input invalid given", @@ -82,7 +82,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, struct{ Test1 string }) {}, FnCtx: func(context.Context, struct{ Test1 string }) {}, - Err: errWrongParamTypeFromConfig, + Err: ErrWrongParamTypeFromConfig, }, { Name: "1 input valid given", @@ -100,7 +100,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, struct{}) {}, FnCtx: func(context.Context, struct{}) {}, - Err: errMissingConfigArgument, + Err: ErrMissingConfigArgument, }, { Name: "1 input ptr invalid given", @@ -109,7 +109,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, struct{ Test1 string }) {}, FnCtx: func(context.Context, struct{ Test1 string }) {}, - Err: errWrongParamTypeFromConfig, + Err: ErrWrongParamTypeFromConfig, }, { Name: "1 input ptr invalid ptr type given", @@ -118,7 +118,7 @@ func TestInputCheck(t *testing.T) { }, Fn: func(context.Context, struct{ Test1 *string }) {}, FnCtx: func(context.Context, struct{ Test1 *string }) {}, - Err: errWrongParamTypeFromConfig, + Err: ErrWrongParamTypeFromConfig, }, { Name: "1 input ptr valid given", @@ -261,13 +261,13 @@ func TestOutputCheck(t *testing.T) { { Output: map[string]reflect.Type{}, Fn: func(context.Context) {}, - Err: errMissingHandlerOutputArgument, + Err: ErrMissingHandlerOutputArgument, }, // no input -> with last type not api.Err { Output: map[string]reflect.Type{}, Fn: func(context.Context) bool { return true }, - Err: errMissingHandlerErrorArgument, + Err: ErrMissingHandlerErrorArgument, }, // no input -> with api.Err { @@ -279,13 +279,13 @@ func TestOutputCheck(t *testing.T) { { Output: map[string]reflect.Type{}, Fn: func(context.Context) api.Err { return api.ErrSuccess }, - Err: errMissingHandlerContextArgument, + Err: ErrMissingHandlerContextArgument, }, // no input -> invlaid context.Context type { Output: map[string]reflect.Type{}, Fn: func(context.Context, int) api.Err { return api.ErrSuccess }, - Err: errMissingHandlerContextArgument, + Err: ErrMissingHandlerContextArgument, }, // func can have output if not specified { @@ -299,7 +299,7 @@ func TestOutputCheck(t *testing.T) { "Test1": reflect.TypeOf(int(0)), }, Fn: func() api.Err { return api.ErrSuccess }, - Err: errWrongOutputArgumentType, + Err: ErrWrongOutputArgumentType, }, // output not a pointer { @@ -307,7 +307,7 @@ func TestOutputCheck(t *testing.T) { "Test1": reflect.TypeOf(int(0)), }, Fn: func() (int, api.Err) { return 0, api.ErrSuccess }, - Err: errWrongOutputArgumentType, + Err: ErrWrongOutputArgumentType, }, // output not a pointer to struct { @@ -315,7 +315,7 @@ func TestOutputCheck(t *testing.T) { "Test1": reflect.TypeOf(int(0)), }, Fn: func() (*int, api.Err) { return nil, api.ErrSuccess }, - Err: errWrongOutputArgumentType, + Err: ErrWrongOutputArgumentType, }, // unexported param name { @@ -323,7 +323,7 @@ func TestOutputCheck(t *testing.T) { "test1": reflect.TypeOf(int(0)), }, Fn: func() (*struct{}, api.Err) { return nil, api.ErrSuccess }, - Err: errUnexportedName, + Err: ErrUnexportedName, }, // output field missing { @@ -331,7 +331,7 @@ func TestOutputCheck(t *testing.T) { "Test1": reflect.TypeOf(int(0)), }, Fn: func() (*struct{}, api.Err) { return nil, api.ErrSuccess }, - Err: errMissingConfigArgument, + Err: ErrMissingConfigArgument, }, // output field invalid type { @@ -339,7 +339,7 @@ func TestOutputCheck(t *testing.T) { "Test1": reflect.TypeOf(int(0)), }, Fn: func() (*struct{ Test1 string }, api.Err) { return nil, api.ErrSuccess }, - Err: errWrongParamTypeFromConfig, + Err: ErrWrongParamTypeFromConfig, }, // output field valid type {