The question is how to validate syntax in json file in golang? I know that I can unmarshal slice of bytes and get standard error if I missed comma or brackets. How to get line in file where it happens?
If the error is a syntax error in the input JSON then the error returned from the unmarshal will be a *json.SyntaxError
:
https://golang.org/pkg/encoding/json/#SyntaxError
This contains the position in the input byte slice that caused the error as it's Offset field. To get this you do a type switch to check if it's this type of error and convert it to this type to get the offset value out of it as per the instructions here:
https://tour.golang.org/methods/16
You can then use a bufio Scanner to find the line number:
https://golang.org/pkg/bufio/#Scanner
Putting this all together you have this code:
package main
import (
"fmt"
"encoding/json"
)
const myJSON = `
{
"totallyValid": "this is OK",
"missing quotes: not OK
}
`
func main() {
var result map[string]interface{}
err := json.Unmarshal([]byte(myJSON), &result)
switch err := err.(type) {
case *json.SyntaxError:
fmt.Printf("Error in input syntax at byte %d: %s
", err.Offset, err.Error())
var line int
var readBytes int64
for scanner.Scan() {
// +1 for the
character
readBytes += int64(len(scanner.Bytes()) + 1)
line += 1
if (readBytes >= err.Offset) {
fmt.Printf("Error in input syntax on line %d: %s
", line, err.Error())
break
}
}
default:
fmt.Printf("Other error decoding JSON: %s
", err.Error())
}
}
This is runnable here: