Skip to content

Commit

Permalink
Nicer error when list/map assigned to string argument.
Browse files Browse the repository at this point in the history
Previous this would return the following sort of error:
expected type 'string', got unconvertible type '[]interface {}'

This is the raw error returned by the underlying mapstructure library.
This is not a helpful error message for anyone who doesn't know Go's
type system, and it exposes Terraform's internals to the UI.

Instead we'll catch these cases before we try to use mapstructure and
return a more straightforward message.

By checking the type before the IsComputed exception this also avoids
a crash caused when the assigned value is a computed list. Otherwise
the list of interpolations is allowed through here and then crashes later
during Diff when the value is not a primitive as expected.
  • Loading branch information
apparentlymart committed Oct 23, 2015
1 parent 6a8ae92 commit a671825
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
19 changes: 18 additions & 1 deletion helper/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -1178,8 +1178,25 @@ func (m schemaMap) validatePrimitive(
raw interface{},
schema *Schema,
c *terraform.ResourceConfig) ([]string, []error) {

// Catch if the user gave a complex type where a primitive was
// expected, so we can return a friendly error message that
// doesn't contain Go type system terminology.
switch reflect.ValueOf(raw).Type().Kind() {
case reflect.Slice:
return nil, []error{
fmt.Errorf("%s must be a single value, not a list", k),
}
case reflect.Map:
return nil, []error{
fmt.Errorf("%s must be a single value, not a map", k),
}
default: // ok
}

if c.IsComputed(k) {
// If the key is being computed, then it is not an error
// If the key is being computed, then it is not an error as
// long as it's not a slice or map.
return nil, nil
}

Expand Down
30 changes: 30 additions & 0 deletions helper/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3409,6 +3409,36 @@ func TestSchemaMap_Validate(t *testing.T) {
Err: true,
},

"Bad, should not allow lists to be assigned to string attributes": {
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Required: true,
},
},

Config: map[string]interface{}{
"availability_zone": []interface{}{"foo", "bar", "baz"},
},

Err: true,
},

"Bad, should not allow maps to be assigned to string attributes": {
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Required: true,
},
},

Config: map[string]interface{}{
"availability_zone": map[string]interface{}{"foo": "bar", "baz": "thing"},
},

Err: true,
},

"Deprecated attribute usage generates warning, but not error": {
Schema: map[string]*Schema{
"old_news": &Schema{
Expand Down

0 comments on commit a671825

Please sign in to comment.