diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 839ad4a31..00b3d917a 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -330,6 +330,11 @@ func cleanupParseError(filename string, err error) error { return fmt.Errorf("parse error at (%s): %s", string(location), errMsg) } +type TraceableError struct { + location string + message string +} + func cleanupExecError(filename string, err error) error { if _, isExecError := err.(template.ExecError); !isExecError { return err @@ -349,8 +354,51 @@ func cleanupExecError(filename string, err error) error { if len(parts) >= 2 { return fmt.Errorf("execution error at (%s): %s", string(location), parts[1]) } + current := err + fileLocations := []TraceableError{} + for { + if current == nil { + break + } + tokens = strings.SplitN(current.Error(), ": ", 3) + location = tokens[1] + traceable := TraceableError{ + location: location, + message: current.Error(), + } + fileLocations = append(fileLocations, traceable) + current = errors.Unwrap(current) + } + + prevMessage := "" + for i := len(fileLocations) - 1; i >= 0; i-- { + currentMsg := fileLocations[i].message + if i == len(fileLocations)-1 { + prevMessage = currentMsg + continue + } + + if strings.Contains(currentMsg, prevMessage) { + fileLocations[i].message = strings.ReplaceAll(fileLocations[i].message, prevMessage, "") + } + prevMessage = currentMsg + } + + for i := len(fileLocations) - 1; i >= 0; i-- { + if strings.Contains(fileLocations[i].message, fileLocations[i].location) { + fileLocations[i].message = strings.ReplaceAll(fileLocations[i].message, fileLocations[i].location, "") + } + } + + finalErrorString := "" + for _, i := range fileLocations { + if i.message == "" { + continue + } + finalErrorString = finalErrorString + "\n" + i.location + " " + i.message + } - return err + return fmt.Errorf("%s\n\n\n\nError: %s", finalErrorString, err.Error()) } func sortTemplates(tpls map[string]renderable) []string { diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 68e0158fa..8445abf83 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -18,6 +18,8 @@ package engine import ( "fmt" + "github.com/stretchr/testify/assert" + "helm.sh/helm/v4/pkg/chart/v2/loader" "path" "strings" "sync" @@ -1301,6 +1303,25 @@ func TestRenderTplMissingKeyString(t *testing.T) { } } +func TestSometimesJesseJustBe(t *testing.T) { + c, _ := loader.Load("/home/jesse/code/camunda-platform-helm/charts/camunda-platform-8.5") + + v, _ := chartutil.ReadValuesFile("/home/jesse/code/helm/values.yaml") + val, _ := chartutil.CoalesceValues(c, v) + vals := map[string]interface{}{ + "Values": val.AsMap(), + } + out, err := Render(c, vals) + + if err != nil { + t.Errorf("Failed to render templates: %s", err) + } + assert.NotNil(t, out) + data := strings.TrimSpace(out["jesse-subchart-values-hacktest/charts/keycloak/templates/ingress.yaml"]) + fmt.Println(data) + assert.NotEmpty(t, data) +} + func TestRenderCustomTemplateFuncs(t *testing.T) { // Create a chart with two templates that use custom functions c := &chart.Chart{