From 110ef68af305f2e6cf1dd68b84475493e9c1395b Mon Sep 17 00:00:00 2001 From: Tom van Dinther <39470469+tvandinther@users.noreply.github.com> Date: Sun, 5 Jan 2025 15:34:49 +0100 Subject: [PATCH] Improve error handling (#13) --- pkg/plugin/helm.go | 16 ++++++---- pkg/util/manifests.go | 69 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/pkg/plugin/helm.go b/pkg/plugin/helm.go index f9634e2..68c88f1 100644 --- a/pkg/plugin/helm.go +++ b/pkg/plugin/helm.go @@ -41,11 +41,14 @@ func init() { } var chart ChartArg - util.MapToStruct(chartArgMap, &chart) + err := util.MapToStruct(chartArgMap, &chart) + if err != nil { + return nil, fmt.Errorf("unable to map chart to struct: %w", err) + } - err := validate(&chart) + err = validate(&chart) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid chart: %w", err) } release, err := helm.RunTemplate(&helm.ChartRef{ @@ -54,16 +57,17 @@ func init() { Version: chart.Version, }, chart.Values, chart.ReleaseName, chart.Namespace, chart.Capabilities.APIVersions) if err != nil { - return nil, err + return nil, fmt.Errorf("problem templating helm chart: %w", err) } splitManifests := releaseutil.SplitManifests(release.Manifest) - var manifestSlice []types.Manifest for _, manifestString := range splitManifests { var manifest types.Manifest yaml.Unmarshal([]byte(manifestString), &manifest) - manifestSlice = append(manifestSlice, manifest) + if len(manifest) > 0 { + manifestSlice = append(manifestSlice, manifest) + } } util.SortManifests(manifestSlice) diff --git a/pkg/util/manifests.go b/pkg/util/manifests.go index ce1da75..caff611 100644 --- a/pkg/util/manifests.go +++ b/pkg/util/manifests.go @@ -1,36 +1,77 @@ package util import ( + "fmt" "slices" "strings" "knit/pkg/types" ) -func SortManifests(manifests []types.Manifest) { +func SortManifests(manifests []types.Manifest) error { + errors := make([]error, 0) slices.SortFunc(manifests, func(a, b types.Manifest) int { - return compareManifests(a, b, - func(x types.Manifest) string { return x["apiVersion"].(string) }, - func(x types.Manifest) string { return x["kind"].(string) }, - func(x types.Manifest) string { - metadata := x["metadata"].(map[string]any) - return metadata["name"].(string) + comp, err := compareManifests(a, b, + func(x types.Manifest) (string, error) { return getFromMap[string](x, "apiVersion") }, + func(x types.Manifest) (string, error) { return getFromMap[string](x, "kind") }, + func(x types.Manifest) (string, error) { + metadata, err := getFromMap[map[string]any](x, "metadata") + if err != nil { + return "", err + } + return getFromMap[string](metadata, "name") }, - func(x types.Manifest) string { - metadata := x["metadata"].(map[string]any) - return metadata["generateName"].(string) + func(x types.Manifest) (string, error) { + metadata, err := getFromMap[map[string]any](x, "metadata") + if err != nil { + return "", err + } + return getFromMap[string](metadata, "generateName") }) + if err != nil { + errors = append(errors, err) + } + + return comp }) + + if len(errors) != 0 { + var errorString string + for _, err := range errors { + errorString += err.Error() + } + return fmt.Errorf("encountered %d errors during sorting\n%s", len(errors), errorString) + } + + return nil } -func compareManifests(a, b types.Manifest, selectors ...func(x types.Manifest) string) int { +func getFromMap[T any](manifest map[string]any, key string) (T, error) { + str, ok := manifest[key].(T) + if !ok { + var none T + return none, fmt.Errorf("%s of manifest can not be converted to string\n%+v", key, manifest) + } + + return str, nil +} + +func compareManifests(a, b types.Manifest, selectors ...func(x types.Manifest) (string, error)) (int, error) { var comparator int for _, selector := range selectors { - comparator = strings.Compare(selector(a), selector(b)) + strA, err := selector(a) + if err != nil { + return 0, err + } + strB, err := selector(b) + if err != nil { + return 0, err + } + comparator = strings.Compare(strA, strB) if comparator != 0 { - return comparator + return comparator, nil } } - return 0 + return 0, nil }