|
4 | 4 | "encoding/json" |
5 | 5 | "errors" |
6 | 6 | "fmt" |
| 7 | + "io" |
| 8 | + "log" |
7 | 9 | "os" |
8 | 10 | "path/filepath" |
9 | 11 | "runtime" |
@@ -143,15 +145,28 @@ func (c *Config) read() error { |
143 | 145 |
|
144 | 146 | if err := json.NewDecoder(f).Decode(&c); err != nil { |
145 | 147 | var extra string |
146 | | - if _, ok := err.(*json.SyntaxError); ok { |
147 | | - extra = ":\nThe file contains invalid JSON syntax" |
| 148 | + if serr, ok := err.(*json.SyntaxError); ok { |
| 149 | + if _, serr := f.Seek(0, os.SEEK_SET); serr != nil { |
| 150 | + log.Fatalf("seek error: %v", serr) |
| 151 | + } |
| 152 | + extra = fmt.Sprintf(":\nThe file contains invalid JSON syntax at '%s' <~", |
| 153 | + findInvalidJSON(f, serr.Offset)) |
148 | 154 | } |
149 | | - return fmt.Errorf("error parsing JSON in the config file %s%s: %s", f.Name(), extra, err) |
| 155 | + return fmt.Errorf("error parsing JSON in the config file %s%s\n%s", f.Name(), extra, err) |
150 | 156 | } |
151 | 157 |
|
152 | 158 | return nil |
153 | 159 | } |
154 | 160 |
|
| 161 | +func findInvalidJSON(f io.ReaderAt, pos int64) string { |
| 162 | + buf := make([]byte, 13) |
| 163 | + if _, err := f.ReadAt(buf, pos-13); err != nil { |
| 164 | + log.Fatalf("read error: %v", err) |
| 165 | + } |
| 166 | + |
| 167 | + return string(buf) |
| 168 | +} |
| 169 | + |
155 | 170 | // IsAuthenticated returns true if the config contains an API key. |
156 | 171 | // This does not check whether or not that key is valid. |
157 | 172 | func (c *Config) IsAuthenticated() bool { |
|
0 commit comments