mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-26 00:41:27 -06:00
tfdiags: helper functions for nicer display of cty.PathError
cty doesn't have a native string representation of a cty.Path because it is the layer below any particular syntax, but up here in Terraform land we know that we use HCL native syntax and so we can format a string in a HCL-ish way for familiarity to the user. We'll use this form automatically when such an error is used directly as a diagnostic, but we also expose the function publicly so that other code that incorporates errors into diagnostic detail strings can apply the same formatting.
This commit is contained in:
parent
e309675853
commit
9bd47bf17c
56
tfdiags/config_traversals.go
Normal file
56
tfdiags/config_traversals.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package tfdiags
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FormatCtyPath is a helper function to produce a user-friendly string
|
||||||
|
// representation of a cty.Path. The result uses a syntax similar to the
|
||||||
|
// HCL expression language in the hope of it being familiar to users.
|
||||||
|
func FormatCtyPath(path cty.Path) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for _, step := range path {
|
||||||
|
switch ts := step.(type) {
|
||||||
|
case cty.GetAttrStep:
|
||||||
|
fmt.Fprintf(&buf, ".%s", ts.Name)
|
||||||
|
case cty.IndexStep:
|
||||||
|
buf.WriteByte('[')
|
||||||
|
key := ts.Key
|
||||||
|
keyTy := key.Type()
|
||||||
|
switch {
|
||||||
|
case key.IsNull():
|
||||||
|
buf.WriteString("null")
|
||||||
|
case !key.IsKnown():
|
||||||
|
buf.WriteString("(not yet known)")
|
||||||
|
case keyTy == cty.Number:
|
||||||
|
bf := key.AsBigFloat()
|
||||||
|
buf.WriteString(bf.Text('g', -1))
|
||||||
|
case keyTy == cty.String:
|
||||||
|
buf.WriteString(strconv.Quote(key.AsString()))
|
||||||
|
default:
|
||||||
|
buf.WriteString("...")
|
||||||
|
}
|
||||||
|
buf.WriteByte(']')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatError is a helper function to produce a user-friendly string
|
||||||
|
// representation of certain special error types that we might want to
|
||||||
|
// include in diagnostic messages.
|
||||||
|
//
|
||||||
|
// This currently has special behavior only for cty.PathError, where a
|
||||||
|
// non-empty path is rendered in a HCL-like syntax as context.
|
||||||
|
func FormatError(err error) string {
|
||||||
|
perr, ok := err.(cty.PathError)
|
||||||
|
if !ok || len(perr.Path) == 0 {
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s: %s", FormatCtyPath(perr.Path), perr.Error())
|
||||||
|
}
|
@ -13,7 +13,7 @@ func (e nativeError) Severity() Severity {
|
|||||||
|
|
||||||
func (e nativeError) Description() Description {
|
func (e nativeError) Description() Description {
|
||||||
return Description{
|
return Description{
|
||||||
Summary: e.err.Error(),
|
Summary: FormatError(e.err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user