Merge pull request #38905 from juanvallejo/jvallejo/return-typed-json-yaml-syntax-errs

Automatic merge from submit-queue (batch tested with PRs 38905, 40421)

return typed json,yaml syntax errors

**Release note**:
```release-note
release-note-none
```

This patch creates error types for JSON and YAML syntax errors to make
it easier to handle these types of errors by callers of JSON and YAML
decoders.

@fabianofranz @AdoHe
This commit is contained in:
Kubernetes Submit Queue 2017-01-25 09:49:47 -08:00 committed by GitHub
commit 0c8069bab4
2 changed files with 56 additions and 4 deletions

View File

@ -69,11 +69,10 @@ func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
} }
if len(bytes) != 0 { if len(bytes) != 0 {
data, err := yaml.YAMLToJSON(bytes) err := yaml.Unmarshal(bytes, into)
if err != nil { if err != nil {
return err return YAMLSyntaxError{err}
} }
return json.Unmarshal(data, into)
} }
return err return err
} }
@ -184,6 +183,23 @@ type YAMLOrJSONDecoder struct {
rawData []byte rawData []byte
} }
type JSONSyntaxError struct {
Line int
Err error
}
func (e JSONSyntaxError) Error() string {
return fmt.Sprintf("json: line %d: %s", e.Line, e.Err.Error())
}
type YAMLSyntaxError struct {
err error
}
func (e YAMLSyntaxError) Error() string {
return e.err.Error()
}
// NewYAMLOrJSONDecoder returns a decoder that will process YAML documents // NewYAMLOrJSONDecoder returns a decoder that will process YAML documents
// or JSON documents from the given reader as a stream. bufferSize determines // or JSON documents from the given reader as a stream. bufferSize determines
// how far into the stream the decoder will look to figure out whether this // how far into the stream the decoder will look to figure out whether this
@ -226,7 +242,10 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
start := strings.LastIndex(js[:syntax.Offset], "\n") + 1 start := strings.LastIndex(js[:syntax.Offset], "\n") + 1
line := strings.Count(js[:start], "\n") line := strings.Count(js[:start], "\n")
return fmt.Errorf("json: line %d: %s", line, syntax.Error()) return JSONSyntaxError{
Line: line,
Err: fmt.Errorf(syntax.Error()),
}
} }
} }
return err return err

View File

@ -314,3 +314,36 @@ func testReadLines(t *testing.T, lineLengths []int) {
} }
} }
} }
func TestTypedJSONOrYamlErrors(t *testing.T) {
s := NewYAMLOrJSONDecoder(bytes.NewReader([]byte(`{
"foo": {
"stuff": 1
"otherStuff": 2
}
}
`)), 100)
obj := generic{}
err := s.Decode(&obj)
if err == nil {
t.Fatal("expected error with json: prefix, got no error")
}
if _, ok := err.(JSONSyntaxError); !ok {
t.Fatalf("expected %q to be of type JSONSyntaxError", err.Error())
}
s = NewYAMLOrJSONDecoder(bytes.NewReader([]byte(`---
stuff: 1
test-foo: 1
---
`)), 100)
obj = generic{}
err = s.Decode(&obj)
if err == nil {
t.Fatal("expected error with yaml: prefix, got no error")
}
if _, ok := err.(YAMLSyntaxError); !ok {
t.Fatalf("expected %q to be of type YAMLSyntaxError", err.Error())
}
}