Steve
Steve

Reputation: 55555

How does Go JSON decoding error behavior work?

I'm trying to understand the behavior of JSON decoding and unmarshalling in Go when an error is encountered. In particular, in the following struct, the title field is a different format than is provided by the returned JSON and an error provided. Is the behavior to continue with other fields despite the error, or will processing of the additional fields stop? I haven't found any mention of how this is handled in the standard library.

type Response struct {
    Title struct {
        Text          string `json:"text"`
        Accessibility struct {
            Label      string `json:"label"`
            Identifier string `json:"identifier"`
        } `json:"accessibility"`
    } `json:"title,omitempty"`
    Type    string `json:"type"`
}
{
    "title": "test",
    "type": "type"
}

Upvotes: 0

Views: 1239

Answers (1)

icza
icza

Reputation: 417462

A quick test reveals it:

func main() {
    var r Response
    if err := json.Unmarshal([]byte(src), &r); err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%+v", r)
}

const src = `{
    "title": "test",
    "type": "type"
}

Result (try it on the Go Playground):

json: cannot unmarshal string into Go struct field Response.title of type struct { Text string "json:\"text\""; Accessibility struct { Label string "json:\"label\""; Identifier string "json:\"identifier\"" } "json:\"accessibility\"" }
{Title:{Text: Accessibility:{Label: Identifier:}} Type:type}

A non-nil error is returned while the subsequent Type field gets unmarshaled properly.

In general: An error is returned, while unmarshaling continues without any guarantees.

This is documented at json.Unmarshal():

If a JSON value is not appropriate for a given target type, or if a JSON number overflows the target type, Unmarshal skips that field and completes the unmarshaling as best it can. If no more serious errors are encountered, Unmarshal returns an UnmarshalTypeError describing the earliest such error. In any case, it's not guaranteed that all the remaining fields following the problematic one will be unmarshaled into the target object.

Upvotes: 3

Related Questions