diff --git a/api/internal/kusterr/yamlformaterror.go b/api/internal/kusterr/yamlformaterror.go index 950ffea8a4..aa76d1dd7f 100644 --- a/api/internal/kusterr/yamlformaterror.go +++ b/api/internal/kusterr/yamlformaterror.go @@ -19,6 +19,16 @@ func (e YamlFormatError) Error() string { return fmt.Sprintf("YAML file [%s] encounters a format error.\n%s\n", e.Path, e.ErrorMsg) } +// MalformedYamlError represents an error that occurred while trying to decode a given YAML. +type MalformedYamlError struct { + Path string + ErrorMsg string +} + +func (e MalformedYamlError) Error() string { + return fmt.Sprintf("%s in File: %s", e.ErrorMsg, e.Path) +} + // Handler handles YamlFormatError func Handler(e error, path string) error { if isYAMLSyntaxError(e) { @@ -27,9 +37,19 @@ func Handler(e error, path string) error { ErrorMsg: e.Error(), } } + if IsMalformedYAMLError(e) { + return MalformedYamlError{ + Path: path, + ErrorMsg: e.Error(), + } + } return e } func isYAMLSyntaxError(e error) bool { return strings.Contains(e.Error(), "error converting YAML to JSON") || strings.Contains(e.Error(), "error unmarshaling JSON") } + +func IsMalformedYAMLError(e error) bool { + return strings.Contains(e.Error(), "MalformedYAMLError") +} diff --git a/api/internal/target/kusttarget.go b/api/internal/target/kusttarget.go index 2fcfd830db..4fd758e6a3 100644 --- a/api/internal/target/kusttarget.go +++ b/api/internal/target/kusttarget.go @@ -14,6 +14,7 @@ import ( "sigs.k8s.io/kustomize/api/ifc" "sigs.k8s.io/kustomize/api/internal/accumulator" "sigs.k8s.io/kustomize/api/internal/builtins" + "sigs.k8s.io/kustomize/api/internal/kusterr" "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig" "sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers" "sigs.k8s.io/kustomize/api/internal/plugins/loader" @@ -405,6 +406,9 @@ func (kt *KustTarget) accumulateResources( if errors.Is(errF, load.ErrorHTTP) { return nil, errF } + if kusterr.IsMalformedYAMLError(errF) { // Some error occurred while tyring to decode YAML file + return nil, errF + } ldr, err := kt.ldr.New(path) if err != nil { return nil, errors.Wrapf( diff --git a/api/krusty/basic_io_test.go b/api/krusty/basic_io_test.go index 6a2b9c3026..5e6eef8fd8 100644 --- a/api/krusty/basic_io_test.go +++ b/api/krusty/basic_io_test.go @@ -6,6 +6,7 @@ package krusty_test import ( "testing" + "sigs.k8s.io/kustomize/api/internal/kusterr" kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" ) @@ -80,3 +81,35 @@ spec: clusterIP: None `) } + +//test for https://github.com/kubernetes-sigs/kustomize/issues/3812#issuecomment-862339267 +func TestBasicIO3812(t *testing.T) { + th := kusttest_test.MakeHarness(t) + th.WriteK(".", ` +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - service.yaml +`) + + th.WriteF("service.yaml", ` +apiVersion: v1 +kind: Service +metadata: + name: kapacitor + labels: + app.kubernetes.io/name: tick-kapacitor +spec: + selector: + app.kubernetes.io/name: tick-kapacitor + - name: http + port: 9092 + protocol: TCP + type: ClusterIP +`) + + err := th.RunWithErr(".", th.MakeDefaultOptions()) + if !kusterr.IsMalformedYAMLError(err) { + t.Fatalf("unexpected error: %q", err) + } +} diff --git a/api/krusty/component_test.go b/api/krusty/component_test.go index a76a802844..8d83b56ab5 100644 --- a/api/krusty/component_test.go +++ b/api/krusty/component_test.go @@ -551,7 +551,7 @@ components: `), }, runPath: "filesincomponents", - expectedError: "'/filesincomponents/stub.yaml' must be a directory to be a root", + expectedError: "'/filesincomponents/stub.yaml' must be a directory so that it can used as a build root", }, "invalid-component-api-version": { input: []FileGen{writeTestBase, writeOverlayProd, diff --git a/api/loader/fileloader.go b/api/loader/fileloader.go index 164560d404..ffeef3b02e 100644 --- a/api/loader/fileloader.go +++ b/api/loader/fileloader.go @@ -159,8 +159,8 @@ func demandDirectoryRoot( } if f != "" { return "", fmt.Errorf( - "got file '%s', but '%s' must be a directory to be a root", - f, path) + "'%s' must be a directory so that it can used as a build root", + path) } return d, nil } diff --git a/cmd/config/internal/commands/fmt_test.go b/cmd/config/internal/commands/fmt_test.go index 16ba273899..c0918ac4f5 100644 --- a/cmd/config/internal/commands/fmt_test.go +++ b/cmd/config/internal/commands/fmt_test.go @@ -164,7 +164,7 @@ func TestCmd_failFileContents(t *testing.T) { err := r.Command.Execute() // expect an error - assert.EqualError(t, err, "yaml: line 1: did not find expected node content") + assert.EqualError(t, err, "MalformedYAMLError: yaml: line 1: did not find expected node content") } func TestFmtSubPackages(t *testing.T) { diff --git a/kyaml/kio/byteio_reader.go b/kyaml/kio/byteio_reader.go index 18281a536d..fbcf4b6bef 100644 --- a/kyaml/kio/byteio_reader.go +++ b/kyaml/kio/byteio_reader.go @@ -294,7 +294,7 @@ func (r *ByteReader) decode(originalYAML string, index int, decoder *yaml.Decode return nil, io.EOF } if err != nil { - return nil, errors.Wrap(err) + return nil, errors.WrapPrefixf(err, "MalformedYAMLError") } if yaml.IsYNodeEmptyDoc(node) { diff --git a/kyaml/kio/filters/fmtr_test.go b/kyaml/kio/filters/fmtr_test.go index a79e4eb9bd..697b1c6654 100644 --- a/kyaml/kio/filters/fmtr_test.go +++ b/kyaml/kio/filters/fmtr_test.go @@ -673,7 +673,7 @@ apiVersion: example.com/v1beta1 ` _, err := FormatInput(strings.NewReader(y)) - assert.EqualError(t, err, "yaml: line 15: found character that cannot start any token") + assert.EqualError(t, err, "MalformedYAMLError: yaml: line 15: found character that cannot start any token") } // TestFormatFileOrDirectory_yamlExtFile verifies that FormatFileOrDirectory will format a file