Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ func (i *interpreter) rawevaluate(a ast.Node, tc tailCallStatus) (value, error)
return target.index(i, int(indexInt.value))
}

return nil, i.Error(fmt.Sprintf("Value non indexable: %v", reflect.TypeOf(targetValue)))
return nil, i.Error(fmt.Sprintf("Could not index a value of type %q (only objects, arrays and strings can be indexed)", targetValue.getType().name))

case *ast.Import:
codePath := node.Loc().FileName
Expand Down
29 changes: 29 additions & 0 deletions jsonnet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,32 @@ func TestSetTraceOut(t *testing.T) {
t.Errorf("Expected %q, but got %q", expected, actual)
}
}

func TestIndexNonIndexableErrorMessage(t *testing.T) {
testCases := []struct {
name string
input string
typeName string
}{
{name: "null", input: `null[42]`, typeName: "null"},
{name: "number", input: `(42)[0]`, typeName: "number"},
{name: "boolean", input: `true[0]`, typeName: "boolean"},
{name: "function", input: `(function() 1)[0]`, typeName: "function"},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
vm := MakeVM()
_, err := vm.EvaluateAnonymousSnippet("test.jsonnet", tc.input)
if err == nil {
t.Fatalf("expected error, got nil")
}
if !strings.Contains(err.Error(), tc.typeName) {
t.Errorf("error %q should mention the jsonnet type %q", err.Error(), tc.typeName)
}
if strings.Contains(err.Error(), "jsonnet.value") {
t.Errorf("error %q should not leak internal Go type names", err.Error())
}
})
}
}