mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-25 16:31:10 -06:00
d96284f2e2
When presenting an error that may be a PathError, the error's path is usually relative to some other value. If the caller is able to express that value (or, more often, a reference to it) in HCL syntax then this method will produce a complete expression in the error message, concatenating any path information from the error to the end of the given prefix string.
69 lines
1.9 KiB
Go
69 lines
1.9 KiB
Go
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())
|
|
}
|
|
|
|
// FormatErrorPrefixed is like FormatError except that it presents any path
|
|
// information after the given prefix string, which is assumed to contain
|
|
// an HCL syntax representation of the value that errors are relative to.
|
|
func FormatErrorPrefixed(err error, prefix string) string {
|
|
perr, ok := err.(cty.PathError)
|
|
if !ok || len(perr.Path) == 0 {
|
|
return fmt.Sprintf("%s: %s", prefix, err.Error())
|
|
}
|
|
|
|
return fmt.Sprintf("%s%s: %s", prefix, FormatCtyPath(perr.Path), perr.Error())
|
|
}
|