diff --git a/pkg/devfile/parse.go b/pkg/devfile/parse.go index ada87de2..d9a3ab0f 100644 --- a/pkg/devfile/parse.go +++ b/pkg/devfile/parse.go @@ -18,6 +18,7 @@ package devfile import ( "github.com/devfile/api/v2/pkg/validation/variables" "github.com/devfile/library/v2/pkg/devfile/parser" + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" "github.com/devfile/library/v2/pkg/devfile/validate" ) @@ -121,7 +122,7 @@ func ParseDevfileAndValidate(args parser.ParserArgs) (d parser.DevfileObj, varWa // generic validation on devfile content err = validate.ValidateDevfileData(d.Data) if err != nil { - return d, varWarning, err + return d, varWarning, &errPkg.NonCompliantDevfile{Err: err.Error()} } return d, varWarning, err diff --git a/pkg/devfile/parser/context/apiVersion.go b/pkg/devfile/parser/context/apiVersion.go index 5cea0ce4..5ceffe6a 100644 --- a/pkg/devfile/parser/context/apiVersion.go +++ b/pkg/devfile/parser/context/apiVersion.go @@ -21,7 +21,7 @@ import ( "strings" "github.com/devfile/library/v2/pkg/devfile/parser/data" - "github.com/pkg/errors" + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" "k8s.io/klog" ) @@ -32,7 +32,7 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error { var r map[string]interface{} err := json.Unmarshal(d.rawContent, &r) if err != nil { - return errors.Wrapf(err, "failed to decode devfile json") + return &errPkg.NonCompliantDevfile{Err: err.Error()} } // Get "schemaVersion" value from map for devfile V2 @@ -47,10 +47,10 @@ func (d *DevfileCtx) SetDevfileAPIVersion() error { if okSchema { // SchemaVersion cannot be empty if schemaVersion.(string) == "" { - return fmt.Errorf("schemaVersion in devfile: %s cannot be empty", devfilePath) + return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion in devfile: %s cannot be empty", devfilePath)} } } else { - return fmt.Errorf("schemaVersion not present in devfile: %s", devfilePath) + return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion not present in devfile: %s", devfilePath)} } // Successful diff --git a/pkg/devfile/parser/context/apiVersion_test.go b/pkg/devfile/parser/context/apiVersion_test.go index 282f1fcc..05ea9f2a 100644 --- a/pkg/devfile/parser/context/apiVersion_test.go +++ b/pkg/devfile/parser/context/apiVersion_test.go @@ -19,6 +19,8 @@ import ( "fmt" "reflect" "testing" + + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" ) func TestSetDevfileAPIVersion(t *testing.T) { @@ -29,6 +31,7 @@ func TestSetDevfileAPIVersion(t *testing.T) { concreteSchema = `{"schemaVersion": "2.2.0-latest"}` emptyJson = "{}" emptySchemaVersionJson = `{"schemaVersion": ""}` + badJson = `{"name": "Joe", "age": null]` devfilePath = "/testpath/devfile.yaml" devfileURL = "http://server/devfile.yaml" ) @@ -56,13 +59,19 @@ func TestSetDevfileAPIVersion(t *testing.T) { name: "schemaVersion not present", devfileCtx: DevfileCtx{rawContent: []byte(emptyJson), absPath: devfilePath}, want: "", - wantErr: fmt.Errorf("schemaVersion not present in devfile: %s", devfilePath), + wantErr: &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion not present in devfile: %s", devfilePath)}, }, { name: "schemaVersion empty", devfileCtx: DevfileCtx{rawContent: []byte(emptySchemaVersionJson), url: devfileURL}, want: "", - wantErr: fmt.Errorf("schemaVersion in devfile: %s cannot be empty", devfileURL), + wantErr: &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("schemaVersion in devfile: %s cannot be empty", devfileURL)}, + }, + { + name: "unmarshal error", + devfileCtx: DevfileCtx{rawContent: []byte(badJson), url: devfileURL}, + want: "", + wantErr: &errPkg.NonCompliantDevfile{Err: "invalid character ']' after object key:value pair"}, }, } diff --git a/pkg/devfile/parser/context/content.go b/pkg/devfile/parser/context/content.go index 6f755877..cc83b719 100644 --- a/pkg/devfile/parser/context/content.go +++ b/pkg/devfile/parser/context/content.go @@ -19,6 +19,7 @@ import ( "bytes" "unicode" + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util" "github.com/devfile/library/v2/pkg/util" "github.com/pkg/errors" @@ -42,7 +43,7 @@ func YAMLToJSON(data []byte) ([]byte, error) { // Is YAML, convert to JSON data, err := yaml.YAMLToJSON(data) if err != nil { - return data, errors.Wrapf(err, "failed to convert devfile yaml to json") + return data, &errPkg.NonCompliantDevfile{Err: err.Error()} } // Successful diff --git a/pkg/devfile/parser/context/context_test.go b/pkg/devfile/parser/context/context_test.go index 9f2dc4d1..3d93c6e7 100644 --- a/pkg/devfile/parser/context/context_test.go +++ b/pkg/devfile/parser/context/context_test.go @@ -26,7 +26,7 @@ import ( ) func TestPopulateFromBytes(t *testing.T) { - failedToConvertYamlErr := "failed to convert devfile yaml to json: yaml: mapping values are not allowed in this context" + failedToConvertYamlErr := "mapping values are not allowed in this context" tests := []struct { name string diff --git a/pkg/devfile/parser/context/schema.go b/pkg/devfile/parser/context/schema.go index ca8f37cf..d5c32b06 100644 --- a/pkg/devfile/parser/context/schema.go +++ b/pkg/devfile/parser/context/schema.go @@ -19,6 +19,7 @@ import ( "fmt" "github.com/devfile/library/v2/pkg/devfile/parser/data" + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" "github.com/pkg/errors" "github.com/xeipuuv/gojsonschema" "k8s.io/klog" @@ -30,7 +31,7 @@ func (d *DevfileCtx) SetDevfileJSONSchema() error { // Check if json schema is present for the given apiVersion jsonSchema, err := data.GetDevfileJSONSchema(d.apiVersion) if err != nil { - return err + return &errPkg.NonCompliantDevfile{Err: err.Error()} } d.jsonSchema = jsonSchema return nil @@ -54,7 +55,7 @@ func (d *DevfileCtx) ValidateDevfileSchema() error { for _, desc := range result.Errors() { errMsg = errMsg + fmt.Sprintf("- %s\n", desc) } - return fmt.Errorf(errMsg) + return &errPkg.NonCompliantDevfile{Err: errMsg} } // Sucessful diff --git a/pkg/devfile/parser/errors/errors.go b/pkg/devfile/parser/errors/errors.go new file mode 100644 index 00000000..4df1c087 --- /dev/null +++ b/pkg/devfile/parser/errors/errors.go @@ -0,0 +1,31 @@ +// +// Copyright 2024 Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package errors + +import "fmt" + +// NonCompliantDevfile returns an error if devfile parsing failed due to Non-Compliant Devfile +type NonCompliantDevfile struct { + Err string +} + +func (e *NonCompliantDevfile) Error() string { + errMsg := "error parsing devfile because of non-compliant data" + if e.Err != "" { + errMsg = fmt.Sprintf("%s due to %v", errMsg, e.Err) + } + return errMsg +} diff --git a/pkg/devfile/parser/parse.go b/pkg/devfile/parser/parse.go index 33d555df..26ded19e 100644 --- a/pkg/devfile/parser/parse.go +++ b/pkg/devfile/parser/parse.go @@ -30,6 +30,7 @@ import ( devfileCtx "github.com/devfile/library/v2/pkg/devfile/parser/context" "github.com/devfile/library/v2/pkg/devfile/parser/data" "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common" + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" "github.com/devfile/library/v2/pkg/util" registryLibrary "github.com/devfile/registry-support/registry-library/library" "k8s.io/apimachinery/pkg/types" @@ -65,7 +66,7 @@ func parseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolver // Unmarshal devfile content into devfile struct err = json.Unmarshal(d.Ctx.GetDevfileContent(), &d.Data) if err != nil { - return d, errors.Wrapf(err, "failed to decode devfile content") + return d, &errPkg.NonCompliantDevfile{Err: err.Error()} } if flattenedDevfile { @@ -156,14 +157,14 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) { if args.Data != nil { d.Ctx, err = devfileCtx.NewByteContentDevfileCtx(args.Data) if err != nil { - return d, errors.Wrap(err, "failed to set devfile content from bytes") + return d, err } } else if args.Path != "" { d.Ctx = devfileCtx.NewDevfileCtx(args.Path) } else if args.URL != "" { d.Ctx = devfileCtx.NewURLDevfileCtx(args.URL) } else { - return d, errors.Wrap(err, "the devfile source is not provided") + return d, fmt.Errorf("the devfile source is not provided") } if args.Token != "" { @@ -196,7 +197,7 @@ func ParseDevfile(args ParserArgs) (d DevfileObj, err error) { d, err = populateAndParseDevfile(d, &resolutionContextTree{}, tool, flattenedDevfile) if err != nil { - return d, errors.Wrap(err, "failed to populateAndParseDevfile") + return d, err } setBooleanDefaults := true @@ -249,7 +250,7 @@ type resolverTools struct { func populateAndParseDevfile(d DevfileObj, resolveCtx *resolutionContextTree, tool resolverTools, flattenedDevfile bool) (DevfileObj, error) { var err error if err = resolveCtx.hasCycle(); err != nil { - return DevfileObj{}, err + return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: err.Error()} } // Fill the fields of DevfileCtx struct if d.Ctx.GetURL() != "" { @@ -330,7 +331,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool case parent.Kubernetes != nil: parentDevfileObj, err = parseFromKubeCRD(parent.ImportReference, resolveCtx, tool) default: - return fmt.Errorf("devfile parent does not define any resources") + err = &errPkg.NonCompliantDevfile{Err: "devfile parent does not define any resources"} } if err != nil { return err @@ -347,7 +348,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool } if parentDevfileVerson.GreaterThan(mainDevfileVersion) { - return fmt.Errorf("the parent devfile version from %v is greater than the child devfile version from %v", resolveImportReference(parent.ImportReference), resolveImportReference(resolveCtx.importReference)) + return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the parent devfile version from %v is greater than the child devfile version from %v", resolveImportReference(parent.ImportReference), resolveImportReference(resolveCtx.importReference))} } } parentWorkspaceContent := parentDevfileObj.Data.GetDevfileWorkspaceSpecContent() @@ -392,7 +393,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool case plugin.Kubernetes != nil: pluginDevfileObj, err = parseFromKubeCRD(plugin.ImportReference, resolveCtx, tool) default: - return fmt.Errorf("plugin %s does not define any resources", component.Name) + err = &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("plugin %s does not define any resources", component.Name)} } if err != nil { return err @@ -408,7 +409,7 @@ func parseParentAndPlugin(d DevfileObj, resolveCtx *resolutionContextTree, tool return fmt.Errorf("fail to parse version of plugin devfile from: %v", resolveImportReference(component.Plugin.ImportReference)) } if pluginDevfileVerson.GreaterThan(mainDevfileVersion) { - return fmt.Errorf("the plugin devfile version from %v is greater than the child devfile version from %v", resolveImportReference(component.Plugin.ImportReference), resolveImportReference(resolveCtx.importReference)) + return &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the plugin devfile version from %v is greater than the child devfile version from %v", resolveImportReference(component.Plugin.ImportReference), resolveImportReference(resolveCtx.importReference))} } } pluginWorkspaceContent := pluginDevfileObj.Data.GetDevfileWorkspaceSpecContent() @@ -462,7 +463,7 @@ func parseFromURI(importReference v1.ImportReference, curDevfileCtx devfileCtx.D newUri = path.Join(path.Dir(curDevfileCtx.GetAbsPath()), uri) d.Ctx = devfileCtx.NewDevfileCtx(newUri) if util.ValidateFile(newUri) != nil { - return DevfileObj{}, fmt.Errorf("the provided path is not a valid filepath %s", newUri) + return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the provided path is not a valid filepath %s", newUri)} } srcDir := path.Dir(newUri) destDir := path.Dir(curDevfileCtx.GetAbsPath()) @@ -520,7 +521,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio } d.Ctx, err = devfileCtx.NewByteContentDevfileCtx(devfileContent) if err != nil { - return d, errors.Wrap(err, "failed to set devfile content from bytes") + return d, err } newResolveCtx := resolveCtx.appendNode(importReference) @@ -551,7 +552,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio } } } else { - return DevfileObj{}, fmt.Errorf("failed to fetch from registry, registry URL is not provided") + return DevfileObj{}, &errPkg.NonCompliantDevfile{Err: "failed to fetch from registry, registry URL is not provided"} } return DevfileObj{}, fmt.Errorf("failed to get id: %s from registry URLs provided", id) @@ -559,7 +560,7 @@ func parseFromRegistry(importReference v1.ImportReference, resolveCtx *resolutio func getDevfileFromRegistry(id, registryURL, version string, httpTimeout *int) ([]byte, error) { if !strings.HasPrefix(registryURL, "http://") && !strings.HasPrefix(registryURL, "https://") { - return nil, fmt.Errorf("the provided registryURL: %s is not a valid URL", registryURL) + return nil, &errPkg.NonCompliantDevfile{Err: fmt.Sprintf("the provided registryURL: %s is not a valid URL", registryURL)} } param := util.HTTPRequestParams{ URL: fmt.Sprintf("%s/devfiles/%s/%s", registryURL, id, version), @@ -594,7 +595,7 @@ func getResourcesFromRegistry(id, registryURL, destDir string) error { func parseFromKubeCRD(importReference v1.ImportReference, resolveCtx *resolutionContextTree, tool resolverTools) (d DevfileObj, err error) { if tool.k8sClient == nil || tool.context == nil { - return DevfileObj{}, fmt.Errorf("Kubernetes client and context are required to parse from Kubernetes CRD") + return DevfileObj{}, fmt.Errorf("kubernetes client and context are required to parse from Kubernetes CRD") } namespace := importReference.Kubernetes.Namespace diff --git a/pkg/devfile/parser/parse_test.go b/pkg/devfile/parser/parse_test.go index c778923f..83ce13b7 100644 --- a/pkg/devfile/parser/parse_test.go +++ b/pkg/devfile/parser/parse_test.go @@ -3102,8 +3102,8 @@ func Test_parseParentAndPlugin_RecursivelyReference(t *testing.T) { expectedErr := fmt.Sprintf("devfile has an cycle in references: main devfile -> uri: %s%s -> name: %s, namespace: %s -> uri: %s%s -> uri: %s%s", httpPrefix, uri1, name, namespace, httpPrefix, uri2, httpPrefix, uri1) // Unexpected error - if err == nil || !reflect.DeepEqual(expectedErr, err.Error()) { - t.Errorf("Test_parseParentAndPlugin_RecursivelyReference() unexpected error: %v", err) + if err == nil || !strings.Contains(err.Error(), expectedErr) { + t.Errorf("Test_parseParentAndPlugin_RecursivelyReference() error did not match: %v", err) return } @@ -3350,6 +3350,48 @@ commands: kind: deploy isDefault: true` + badDevfile := `schemaVersion: 10.0.0 +metadata: + name: nodejs + version: 2.1.1 + displayName: Node.js Runtime + description: Stack with Node.js 16 +components: + - name: image-build + image: + imageName: nodejs-image:latest + dockerfile: + uri: Dockerfile + buildContext: . + rootRequired: true + - name: kubernetes-deploy + kubernetes: + uri: deploy.yaml + endpoints: + - name: http-3001 + targetPort: 3001 + path: / +commands: + - id: build-image + apply: + component: image-build + - id: deployk8s + apply: + component: kubernetes-deploy + group: + kind: deploy + - id: deploy + composite: + commands: + - build-image + - deployk8s + group: + kind: deploy + isDefault: true` + + badYAML := ` +~: a` + tests := []struct { name string parserArgs ParserArgs @@ -3416,6 +3458,25 @@ commands: }, wantErr: true, }, + { + name: "error out if parser args have no devfile src", + parserArgs: ParserArgs{}, + wantErr: true, + }, + { + name: "error out if parser args have bad YAML", + parserArgs: ParserArgs{ + Data: []byte(badYAML), + }, + wantErr: true, + }, + { + name: "error if parser args have a bad Devfile", + parserArgs: ParserArgs{ + Data: []byte(badDevfile), + }, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -3623,6 +3684,10 @@ func Test_parseParentFromKubeCRD(t *testing.T) { }, } + emptyImportReference := v1.ImportReference{ + Version: "1", + } + importFromKubeCRD := attributes.Attributes{}.PutString(importSourceAttribute, resolveImportReference(kubeCRDReference)) parentOverridesFromMainDevfile := attributes.Attributes{}.PutString(importSourceAttribute, resolveImportReference(kubeCRDReference)).PutString(parentOverrideAttribute, "main devfile") @@ -3664,6 +3729,8 @@ func Test_parseParentFromKubeCRD(t *testing.T) { }, } + noParentImportSrcErr := "parent does not define any resources" + noPluginImportSrcErr := "plugin plugin1 does not define any resources" crdNotFoundErr := "not found" //override all properties @@ -3904,6 +3971,50 @@ func Test_parseParentFromKubeCRD(t *testing.T) { }, wantErr: &crdNotFoundErr, }, + { + name: "should err out if there is no parent import reference", + mainDevfile: DevfileObj{ + Ctx: devfileCtx.NewDevfileCtx(OutputDevfileYamlPath), + Data: &v2.DevfileV2{ + Devfile: v1.Devfile{ + DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ + Parent: &v1.Parent{ + ImportReference: emptyImportReference, + }, + DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{}, + }, + }, + }, + }, + wantErr: &noParentImportSrcErr, + }, + { + name: "should err out if there is no plugin import reference", + mainDevfile: DevfileObj{ + Ctx: devfileCtx.NewDevfileCtx(OutputDevfileYamlPath), + Data: &v2.DevfileV2{ + Devfile: v1.Devfile{ + DevWorkspaceTemplateSpec: v1.DevWorkspaceTemplateSpec{ + DevWorkspaceTemplateSpecContent: v1.DevWorkspaceTemplateSpecContent{ + Components: []v1.Component{ + { + Name: "plugin1", + ComponentUnion: v1.ComponentUnion{ + Plugin: &v1.PluginComponent{ + ImportReference: v1.ImportReference{ + Version: "2", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + wantErr: &noPluginImportSrcErr, + }, } for _, tt := range tests { @@ -4533,6 +4644,9 @@ func Test_parseFromRegistry(t *testing.T) { stagingRegistry = "https://registry.stage.devfile.io" ) + badYAML := ` +~: a` + parentDevfile := DevfileObj{ Data: &v2.DevfileV2{ Devfile: v1.Devfile{ @@ -4590,6 +4704,7 @@ func Test_parseFromRegistry(t *testing.T) { missingRegistryURLErr := "failed to fetch from registry, registry URL is not provided" invalidRegistryURLErr := "Get .* dial tcp: lookup http: .*" resourceDownloadErr := "failed to pull stack from registry .*" + badDevfileErr := "error parsing devfile because of non-compliant data" testServer := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var data []byte @@ -4597,6 +4712,8 @@ func Test_parseFromRegistry(t *testing.T) { if strings.Contains(r.URL.Path, "/devfiles/"+registryId) { if strings.Contains(r.URL.Path, "latest") { data, err = yaml.Marshal(latestParentDevfile.Data) + } else if strings.Contains(r.URL.Path, "bad") { + data = []byte(badYAML) } else if strings.Contains(r.URL.Path, "1.1.0") { data, err = yaml.Marshal(parentDevfile.Data) } else if r.URL.Path == fmt.Sprintf("/devfiles/%s/", registryId) { @@ -4742,6 +4859,17 @@ func Test_parseFromRegistry(t *testing.T) { }, wantErr: &invalidRegistryURLErr, }, + { + name: "should fail if registry returns a bad devfile content", + importReference: v1.ImportReference{ + ImportReferenceUnion: v1.ImportReferenceUnion{ + Id: registryId, + }, + Version: "bad", + RegistryUrl: httpPrefix + registry, + }, + wantErr: &badDevfileErr, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -4786,6 +4914,7 @@ func Test_parseFromKubeCRD(t *testing.T) { } crdNotFoundErr := "not found" + noContextErr := "kubernetes client and context are required to parse from Kubernetes CRD" tests := []struct { name string @@ -4834,6 +4963,20 @@ func Test_parseFromKubeCRD(t *testing.T) { }, wantErr: &crdNotFoundErr, }, + { + name: "should err out on no context", + wantDevFile: parentDevfile, + importReference: v1.ImportReference{ + ImportReferenceUnion: v1.ImportReferenceUnion{ + Kubernetes: &v1.KubernetesCustomResourceImportReference{ + Name: name, + Namespace: namespace, + }, + }, + }, + devWorkspaceResources: map[string]v1.DevWorkspaceTemplate{}, + wantErr: &noContextErr, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -4845,6 +4988,12 @@ func Test_parseFromKubeCRD(t *testing.T) { k8sClient: testK8sClient, context: context.Background(), } + if tt.name == "should err out on no context" { + tool = resolverTools{ + k8sClient: testK8sClient, + context: nil, + } + } got, err := parseFromKubeCRD(tt.importReference, &resolutionContextTree{}, tool) if (err != nil) != (tt.wantErr != nil) { t.Errorf("Test_parseFromKubeCRD() unexpected error: %v, wantErr %v", err, tt.wantErr) diff --git a/pkg/devfile/parser/reader.go b/pkg/devfile/parser/reader.go index e974ed26..ad3bdc9f 100644 --- a/pkg/devfile/parser/reader.go +++ b/pkg/devfile/parser/reader.go @@ -20,6 +20,7 @@ import ( "fmt" "io" + errPkg "github.com/devfile/library/v2/pkg/devfile/parser/errors" parserUtil "github.com/devfile/library/v2/pkg/devfile/parser/util" "github.com/devfile/library/v2/pkg/util" "github.com/pkg/errors" @@ -132,7 +133,7 @@ func ParseKubernetesYaml(values []interface{}) (KubernetesResources, error) { var kubernetesMap map[string]interface{} err = k8yaml.Unmarshal(byteData, &kubernetesMap) if err != nil { - return KubernetesResources{}, err + return KubernetesResources{}, &errPkg.NonCompliantDevfile{Err: err.Error()} } kind := kubernetesMap["kind"] @@ -155,7 +156,7 @@ func ParseKubernetesYaml(values []interface{}) (KubernetesResources, error) { } if err != nil { - return KubernetesResources{}, err + return KubernetesResources{}, &errPkg.NonCompliantDevfile{Err: err.Error()} } }