configs: Include context when variable default has nested problem

Previously this error message was including only the main error message
and ignoring any context about what part of a potential nested data
structure it arose from.

Now we'll use our usual path formatting utility to introduce additional
context whenever a problem arises with a nested value.
This commit is contained in:
Martin Atkins 2024-07-16 16:14:30 -07:00
parent 3ce9e517ae
commit 72de171edd
2 changed files with 56 additions and 2 deletions

View file

@ -14,6 +14,7 @@ import (
"github.com/zclconf/go-cty/cty/convert"
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/tfdiags"
)
// A consistent detail message for all "not a valid identifier" diagnostics.
@ -163,8 +164,11 @@ func decodeVariableBlock(block *hcl.Block, override bool) (*Variable, hcl.Diagno
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid default value for variable",
Detail: fmt.Sprintf("This default value is not compatible with the variable's type constraint: %s.", err),
Subject: attr.Expr.Range().Ptr(),
Detail: fmt.Sprintf(
"This default value is not compatible with the variable's type constraint: %s.",
tfdiags.FormatError(err),
),
Subject: attr.Expr.Range().Ptr(),
})
val = cty.DynamicVal
}

View file

@ -0,0 +1,50 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package configs
import (
"testing"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
)
func TestVariableInvalidDefault(t *testing.T) {
src := `
variable foo {
type = map(object({
foo = bool
}))
default = {
"thingy" = {
foo = "string where bool is expected"
}
}
}
`
hclF, diags := hclsyntax.ParseConfig([]byte(src), "test.tf", hcl.InitialPos)
if diags.HasErrors() {
t.Fatal(diags.Error())
}
_, diags = parseConfigFile(hclF.Body, nil, false, false)
if !diags.HasErrors() {
t.Fatal("unexpected success; want error")
}
for _, diag := range diags {
if diag.Severity != hcl.DiagError {
continue
}
if diag.Summary != "Invalid default value for variable" {
t.Errorf("unexpected diagnostic summary: %q", diag.Summary)
continue
}
if got, want := diag.Detail, `This default value is not compatible with the variable's type constraint: ["thingy"].foo: a bool is required.`; got != want {
t.Errorf("wrong diagnostic detault\ngot: %s\nwant: %s", got, want)
}
}
}