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:
		@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user