Trying to get the following code to skip parse error noise in a JSON data object stream. Basically I want it to skip the ERROR: ...
lines and continue onto the next parseable record.
json.Decoder
has a limited set of methods - so it's unclear how to move the decoder's index forward (say a byte at a time) to move past the noise.
io.Reader
has methods to skip to say the end of the line (or at least try skipping a character at time) - but doing such operations does not (understandably) affect the json.Decoder
's seek state.
Is there a clean way to do this?
https://play.golang.org/p/riIDh9g1Rx
package main
import (
"encoding/json"
"fmt"
"strings"
"time"
)
type event struct {
T time.Time
Desc string
}
var jsonStream = `
{"T":"2017-11-02T16:00:00-04:00","Desc":"window opened"}
{"T":"2017-11-02T16:30:00-04:00","Desc":"window closed"}
{"T":"2017-11-02T16:41:34-04:00","Desc":"front door opened"}
ERROR: retrieving event 1234
{"T":"2017-11-02T16:41:40-04:00","Desc":"front door closed"}
`
func main() {
jsonReader := strings.NewReader(jsonStream)
decodeStream := json.NewDecoder(jsonReader)
i := 0
for decodeStream.More() {
i++
var ev event
if err := decodeStream.Decode(&ev); err != nil {
fmt.Println("parse error: %s", err)
break
}
fmt.Printf("%3d: %+v
", i, ev)
}
}
got:
1: {T:2017-11-02 16:00:00 -0400 -0400 Desc:window opened}
2: {T:2017-11-02 16:30:00 -0400 -0400 Desc:window closed}
3: {T:2017-11-02 16:41:34 -0400 -0400 Desc:front door opened}
parse error: %s invalid character 'E' looking for beginning of value
want:
1: {T:2017-11-02 16:00:00 -0400 -0400 Desc:window opened}
2: {T:2017-11-02 16:30:00 -0400 -0400 Desc:window closed}
3: {T:2017-11-02 16:41:34 -0400 -0400 Desc:front door opened}
4: {T:2017-11-02 16:41:40 -0400 -0400 Desc:front door closed}