Skip to content

Commit

Permalink
feat: improve the error message for bad YAML
Browse files Browse the repository at this point in the history
Attempt to generate some more easily human-parseable error messages for
invalid .lagoon.yml.
  • Loading branch information
smlx committed Nov 1, 2021
1 parent c548265 commit d7e92fa
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
30 changes: 27 additions & 3 deletions internal/lagoonyml/lint.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lagoonyml

import (
"encoding/json"
"errors"
"fmt"
"os"

Expand All @@ -20,9 +22,31 @@ func LintFile(path string, linters ...Linter) error {
if err != nil {
return fmt.Errorf("couldn't read %v: %v", path, err)
}
err = yaml.Unmarshal(rawYAML, &l)
if err != nil {
return fmt.Errorf("couldn't unmarshal %v: %v", path, err)
yamlErr := yaml.Unmarshal(rawYAML, &l)
if yamlErr != nil {
// check to see if this is an indentation error
rawJSON, err := yaml.YAMLToJSON(rawYAML)
if err != nil {
// can't even convert this so return the original error
return fmt.Errorf("couldn't unmarshal %v: %v", path, yamlErr)
}
// json.Unmarshal returns richer errors than yaml.Unmarshal, which helps to
// diagnose exactly what went wrong
err = json.Unmarshal(rawJSON, &l)
var jTypeErr *json.UnmarshalTypeError
if errors.As(err, &jTypeErr) {
// this rawJSON slice will be partial JSON, but JSONToYAML ignores junk
// at the end of the snippet.
badYAML, err := yaml.JSONToYAML(rawJSON[jTypeErr.Offset:])
if err != nil {
// can't convert this snippet, so return the original error
return fmt.Errorf("couldn't unmarshal %v: %v", path, yamlErr)
}
return fmt.Errorf("couldn't unmarshal %v: %v.\nThere appears to be invalid YAML in the `%s` field:\n\n%s",
path, yamlErr, jTypeErr.Field, badYAML)
}
// this isn't a json.UnmarshalTypeError, so just return the original error
return fmt.Errorf("couldn't unmarshal %v: %v", path, yamlErr)
}
for _, linter := range linters {
if err := linter(&l); err != nil {
Expand Down
4 changes: 4 additions & 0 deletions internal/lagoonyml/lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func TestLint(t *testing.T) {
input: "testdata/invalid.3.lagoon.yml",
valid: false,
},
"cronjob as environment": {
input: "testdata/invalid.4.lagoon.yml",
valid: false,
},
}
for name, tc := range testCases {
t.Run(name, func(tt *testing.T) {
Expand Down
23 changes: 23 additions & 0 deletions internal/lagoonyml/testdata/invalid.4.lagoon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
environments:
cronjobs:
- name: a cronjob defined as environment
schedule: "* * * * *"
command: echo "broken definition"
service: cli
main:
routes:
- nginx:
- example.com
- "www.example.com":
tls-acme: 'true'
insecure: Redirect
hsts: max-age=31536000
- "example.com":
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
set_real_ip_from 1.2.3.4/32;
- "dev.example.com":
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
set_real_ip_from 1.2.3.4/32;
add_header Content-type text/plain;

0 comments on commit d7e92fa

Please sign in to comment.