Skip to content

Commit

Permalink
Fail Nexus Operation for incompatible input type (#1800)
Browse files Browse the repository at this point in the history
  • Loading branch information
bergundy authored Feb 3, 2025
1 parent 349283d commit bfd12ac
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
12 changes: 9 additions & 3 deletions internal/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"context"
"errors"
"fmt"
"reflect"
"strings"
"time"

Expand Down Expand Up @@ -2649,13 +2650,18 @@ func (wc *workflowEnvironmentInterceptor) prepareNexusOperationParams(ctx Contex
var ok bool
var operationName string
if operationName, ok = input.Operation.(string); ok {
} else if regOp, ok := input.Operation.(interface{ Name() string }); ok {
} else if regOp, ok := input.Operation.(interface {
Name() string
InputType() reflect.Type
}); ok {
operationName = regOp.Name()
inputType := reflect.TypeOf(input.Input)
if inputType != nil && !inputType.AssignableTo(regOp.InputType()) {
return executeNexusOperationParams{}, fmt.Errorf("cannot assign argument of type %s to type %s for operation %s", inputType.Name(), regOp.InputType().Name(), operationName)
}
} else {
return executeNexusOperationParams{}, fmt.Errorf("invalid 'operation' parameter, must be an OperationReference or a string")
}
// TODO(bergundy): Validate operation types against input once there's a good way to extract the generic types from
// OperationReference in the Nexus Go SDK.

payload, err := dc.ToPayload(input.Input)
if err != nil {
Expand Down
19 changes: 19 additions & 0 deletions test/nexus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,25 @@ func TestSyncOperationFromWorkflow(t *testing.T) {
})
}

func TestInvalidOperationInput(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
tc := newTestContext(t, ctx)

wf := func(ctx workflow.Context) error {
c := workflow.NewNexusClient(tc.endpoint, "test")
fut := c.ExecuteOperation(ctx, workflowOp, 3456, workflow.NexusOperationOptions{})
return fut.Get(ctx, nil)
}
w := worker.New(tc.client, tc.taskQueue, worker.Options{})
w.RegisterWorkflow(wf)
w.Start()
t.Cleanup(w.Stop)
run, err := tc.client.ExecuteWorkflow(ctx, client.StartWorkflowOptions{TaskQueue: tc.taskQueue}, wf)
require.NoError(t, err)
require.ErrorContains(t, run.Get(ctx, nil), `cannot assign argument of type int to type string for operation workflow-op`)
}

func TestSignalOperationFromWorkflow(t *testing.T) {
receiverID := "nexus-signal-receiver-" + uuid.NewString()

Expand Down

0 comments on commit bfd12ac

Please sign in to comment.