Skip to content

WithContext fails on env struct with method resulting in "not enough arguments to call" #600

Closed
@daenney

Description

@daenney

When using a struct to pass the environment and using a method on that struct which takes a context.Context as ctx on the first argument, calling that function in expr fails despite the use of the withContext patcher:

type testEnvContext struct {
	Context context.Context `expr:"ctx"`
}

func (testEnvContext) Fn(ctx context.Context, a int) int {
	return ctx.Value("value").(int) + a
}

func TestWithContext_env_struct(t *testing.T) {
	withContext := patcher.WithContext{Name: "ctx"}

	program, err := expr.Compile(`Fn(40)`, expr.Env(testEnvContext{}), expr.Patch(withContext))
	require.NoError(t, err)

	ctx := context.WithValue(context.Background(), "value", 2)
	env := testEnvContext{
		Context: ctx,
	}

	output, err := expr.Run(program, env)
	require.NoError(t, err)
	require.Equal(t, 42, output)
}
--- FAIL: TestWithContext_env_struct (0.00s)
    /expr/patcher/with_context_test.go:77: 
        	Error Trace:	/expr/patcher/with_context_test.go:77
        	Error:      	Received unexpected error:
        	            	not enough arguments to call Fn (1:1)
        	            	 | Fn(40)
        	            	 | ^
        	Test:       	TestWithContext_env_struct
FAIL
FAIL	github.com/expr-lang/expr/patcher	0.004s
FAIL

Using the example in the docs with the custom visitor does work

type patcher struct{}
var contextType = reflect.TypeOf((*context.Context)(nil)).Elem()
func (patcher) Visit(node *ast.Node) {
callNode, ok := (*node).(*ast.CallNode)
if !ok {
return
}
callNode.Arguments = append([]ast.Node{&ast.IdentifierNode{Value: "ctx"}}, callNode.Arguments...)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions