Skip to content

Commit f243911

Browse files
committed
Error messages when registering workflows
1 parent 4cdf42f commit f243911

File tree

3 files changed

+111
-18
lines changed

3 files changed

+111
-18
lines changed

internal/args/args.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func InputsToArgs(c converter.Converter, fn reflect.Value, inputs []payload.Payl
3737
argT := activityFnT.In(i)
3838

3939
// Insert context if requested
40-
if i == 0 && (isOwnContext(argT) || isContext(argT)) {
40+
if i == 0 && (IsOwnContext(argT) || isContext(argT)) {
4141
addContext = true
4242
continue
4343
}
@@ -66,7 +66,7 @@ func InputsToArgs(c converter.Converter, fn reflect.Value, inputs []payload.Payl
6666
return args, addContext, nil
6767
}
6868

69-
func isOwnContext(inType reflect.Type) bool {
69+
func IsOwnContext(inType reflect.Type) bool {
7070
contextElem := reflect.TypeOf((*sync.Context)(nil)).Elem()
7171
return inType != nil && inType.Implements(contextElem)
7272
}

internal/workflow/registry.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"reflect"
66
"sync"
77

8+
"github.com/cschleiden/go-workflows/internal/args"
89
"github.com/cschleiden/go-workflows/internal/fn"
910
)
1011

@@ -25,10 +26,45 @@ func NewRegistry() *Registry {
2526
}
2627
}
2728

29+
type ErrInvalidWorkflow struct {
30+
msg string
31+
}
32+
33+
func (e *ErrInvalidWorkflow) Error() string {
34+
return e.msg
35+
}
36+
2837
func (r *Registry) RegisterWorkflow(workflow Workflow) error {
2938
r.Lock()
3039
defer r.Unlock()
3140

41+
wfType := reflect.TypeOf(workflow)
42+
if wfType.Kind() != reflect.Func {
43+
return &ErrInvalidWorkflow{"workflow is not a function"}
44+
}
45+
46+
if wfType.NumIn() == 0 {
47+
return &ErrInvalidWorkflow{"workflow does not accept context parameter"}
48+
}
49+
50+
if !args.IsOwnContext(wfType.In(0)) {
51+
return &ErrInvalidWorkflow{"workflow does not accept context as first parameter"}
52+
}
53+
54+
if wfType.NumOut() == 0 {
55+
return &ErrInvalidWorkflow{"workflow must return error"}
56+
}
57+
58+
if wfType.NumOut() > 2 {
59+
return &ErrInvalidWorkflow{"workflow must return at most two values"}
60+
}
61+
62+
errType := reflect.TypeOf((*error)(nil)).Elem()
63+
if (wfType.NumOut() == 1 && !wfType.Out(0).Implements(errType)) ||
64+
(wfType.NumOut() == 2 && !wfType.Out(1).Implements(errType)) {
65+
return &ErrInvalidWorkflow{"workflow must return error as last return value"}
66+
}
67+
3268
name := fn.Name(workflow)
3369
r.workflowMap[name] = workflow
3470

internal/workflow/registry_test.go

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,79 @@ func reg_workflow1(ctx sync.Context) error {
1313
return nil
1414
}
1515

16-
func Test_WorkflowRegistration(t *testing.T) {
17-
r := NewRegistry()
18-
require.NotNil(t, r)
19-
20-
err := r.RegisterWorkflow(reg_workflow1)
21-
require.NoError(t, err)
22-
23-
x, err := r.GetWorkflow("reg_workflow1")
24-
require.NoError(t, err)
25-
26-
fn, ok := x.(func(context sync.Context) error)
27-
require.True(t, ok)
28-
require.NotNil(t, fn)
29-
30-
err = fn(sync.Background())
31-
require.NoError(t, err)
16+
func TestRegistry_RegisterWorkflow(t *testing.T) {
17+
type args struct {
18+
workflow Workflow
19+
}
20+
tests := []struct {
21+
name string
22+
args args
23+
wantName string
24+
wantErr bool
25+
}{
26+
{
27+
name: "valid workflow",
28+
args: args{
29+
workflow: reg_workflow1,
30+
},
31+
wantName: "reg_workflow1",
32+
},
33+
{
34+
name: "valid workflow with results",
35+
args: args{
36+
workflow: func(ctx sync.Context) (int, error) { return 42, nil },
37+
},
38+
},
39+
{
40+
name: "valid workflow with multiple parameters",
41+
args: args{
42+
workflow: func(ctx sync.Context, a, b int) (int, error) { return 42, nil },
43+
},
44+
},
45+
{
46+
name: "missing parameter",
47+
args: args{
48+
workflow: func(ctx context.Context) {},
49+
},
50+
wantErr: true,
51+
},
52+
{
53+
name: "missing error result",
54+
args: args{
55+
workflow: func(ctx sync.Context) {},
56+
},
57+
wantErr: true,
58+
},
59+
{
60+
name: "missing error with results",
61+
args: args{
62+
workflow: func(ctx sync.Context) int { return 42 },
63+
},
64+
wantErr: true,
65+
},
66+
{
67+
name: "missing error with results",
68+
args: args{
69+
workflow: func(ctx sync.Context) int { return 42 },
70+
},
71+
wantErr: true,
72+
},
73+
}
74+
for _, tt := range tests {
75+
t.Run(tt.name, func(t *testing.T) {
76+
r := NewRegistry()
77+
if err := r.RegisterWorkflow(tt.args.workflow); (err != nil) != tt.wantErr {
78+
t.Errorf("Registry.RegisterWorkflow() error = %v, wantErr %v", err, tt.wantErr)
79+
t.FailNow()
80+
}
81+
82+
if tt.wantName != "" {
83+
x, err := r.GetWorkflow(tt.wantName)
84+
require.NoError(t, err)
85+
require.NotNil(t, x)
86+
}
87+
})
88+
}
3289
}
3390

3491
func reg_activity(ctx context.Context) error {

0 commit comments

Comments
 (0)