return typed json,yaml syntax errors

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.
This commit is contained in:
juanvallejo 2016-12-16 16:43:27 -05:00
parent e5fe366eaf
commit ce1200bf1f
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 {
data, err := yaml.YAMLToJSON(bytes)
err := yaml.Unmarshal(bytes, into)
if err != nil {
return err
return YAMLSyntaxError{err}
}
return json.Unmarshal(data, into)
}
return err
}
@ -184,6 +183,23 @@ type YAMLOrJSONDecoder struct {
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
// 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
@ -226,7 +242,10 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
start := strings.LastIndex(js[:syntax.Offset], "\n") + 1
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

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())
}
}