Skip to content

Commit 08a1966

Browse files
author
Sergiusz Urbaniak
committed
schema: add line/col info in case of JSON err
Previously no line/col information was provided if JSON parsing failed. This fixes it. Unfortunately we still cannot determine line/col information in case of schema validation because the original JSON decoderState is lost. Signed-off-by: Sergiusz Urbaniak <[email protected]>
1 parent b72e75a commit 08a1966

File tree

4 files changed

+62
-2
lines changed

4 files changed

+62
-2
lines changed

cmd/oci-image-tool/autodetect.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,16 @@ func autodetect(path string) (string, error) {
8484
}{}
8585

8686
if err := json.NewDecoder(f).Decode(&header); err != nil {
87-
return "", errors.Wrap(err, "unable to parse JSON")
87+
if _, errSeek := f.Seek(0, os.SEEK_SET); errSeek != nil {
88+
return "", errors.Wrap(err, "unable to seek")
89+
}
90+
91+
e := errors.Wrap(
92+
schema.WrapSyntaxError(f, err),
93+
"unable to parse JSON",
94+
)
95+
96+
return "", e
8897
}
8998

9099
switch {

cmd/oci-image-tool/validate.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ func (v *validateCmd) Run(cmd *cobra.Command, args []string) {
9191
var errs []error
9292
if verr, ok := errors.Cause(err).(schema.ValidationError); ok {
9393
errs = verr.Errs
94+
} else if serr, ok := errors.Cause(err).(*schema.SyntaxError); ok {
95+
v.stderr.Printf("%s:%d:%d: validation failed: %v", arg, serr.Line, serr.Col, err)
96+
exitcode = 1
97+
continue
9498
} else {
9599
v.stderr.Printf("%s: validation failed: %v", arg, err)
96100
exitcode = 1

schema/error.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2016 The Linux Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package schema
16+
17+
import (
18+
"encoding/json"
19+
"io"
20+
21+
"go4.org/errorutil"
22+
)
23+
24+
// A SyntaxError is a description of a JSON syntax error
25+
// including line, column and offset in the JSON file.
26+
type SyntaxError struct {
27+
msg string
28+
Line, Col int
29+
Offset int64
30+
}
31+
32+
func (e *SyntaxError) Error() string { return e.msg }
33+
34+
// WrapSyntaxError checks whether the given error is a *json.SyntaxError
35+
// and converts it into a *schema.SyntaxError containing line/col information using the given reader.
36+
// If the given error is not a *json.SyntaxError it is returned unchanged.
37+
func WrapSyntaxError(r io.Reader, err error) error {
38+
if serr, ok := err.(*json.SyntaxError); ok {
39+
line, col, _ := errorutil.HighlightBytePosition(r, serr.Offset)
40+
return &SyntaxError{serr.Error(), line, col, serr.Offset}
41+
}
42+
43+
return err
44+
}

schema/validator.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package schema
1616

1717
import (
18+
"bytes"
1819
"fmt"
1920
"io"
2021
"io/ioutil"
@@ -48,7 +49,9 @@ func (v Validator) Validate(src io.Reader) error {
4849

4950
result, err := gojsonschema.Validate(sl, ml)
5051
if err != nil {
51-
return errors.Wrapf(err, "schema %s: unable to validate manifest", v)
52+
return errors.Wrapf(
53+
WrapSyntaxError(bytes.NewReader(buf), err),
54+
"schema %s: unable to validate", v)
5255
}
5356

5457
if result.Valid() {

0 commit comments

Comments
 (0)