github.phpd.cn/hashicorp/packer@v1.3.2/common/json/unmarshal.go (about) 1 package json 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 ) 8 9 // Unmarshal is wrapper around json.Unmarshal that returns user-friendly 10 // errors when there are syntax errors. 11 func Unmarshal(data []byte, i interface{}) error { 12 err := json.Unmarshal(data, i) 13 if err != nil { 14 syntaxErr, ok := err.(*json.SyntaxError) 15 if !ok { 16 return err 17 } 18 19 // We have a syntax error. Extract out the line number and friends. 20 // https://groups.google.com/forum/#!topic/golang-nuts/fizimmXtVfc 21 newline := []byte{'\x0a'} 22 23 // Calculate the start/end position of the line where the error is 24 start := bytes.LastIndex(data[:syntaxErr.Offset], newline) + 1 25 end := len(data) 26 if idx := bytes.Index(data[start:], newline); idx >= 0 { 27 end = start + idx 28 } 29 30 // Count the line number we're on plus the offset in the line 31 line := bytes.Count(data[:start], newline) + 1 32 pos := int(syntaxErr.Offset) - start - 1 33 34 err = fmt.Errorf("Error in line %d, char %d: %s\n%s", 35 line, pos, syntaxErr, data[start:end]) 36 return err 37 } 38 39 return nil 40 }