fny
fny

Reputation: 33587

JSON Unmarshal Expected Response and Error Message

I'm making a JSON request to a 3rd party API. If my auth token has expired, I receive an {"error": "message"}. If everything checks out, I receive a valid response.

Right now, I call json.Unmarshal twice to parse the response: once to check for the error and once to parse the real data.

Is there any way to avoid calling Unmarshal twice?

type Unknown map[string]interface{}
type Response struct {
    Status   string `json:"status"`
    Strategy string `json:"strategy"`
    Items    []Item `json:"items"`
}
unknown := Unknown{}
json.Unmarshal(jsonData, &unknown)

if val, ok := unknown["error"]; ok {
    fmt.Println(val)
    return
}

response := Response{}
err := json.Unmarshal(jsonData, &response)
if err != nil {
    fmt.Println("There was an error")
    fmt.Println(err)
    return
}

Upvotes: 0

Views: 2347

Answers (1)

mkopriva
mkopriva

Reputation: 38303

You can use embedding to decode everything at once:

type Response struct {
    Status   string `json:"status"`
    Strategy string `json:"strategy"`
    Items    []Item `json:"items"`
}

var dest struct {
    Error string `json:"error"`
    Response // embedded Response
}
if err := json.Unmarshal(jsonData, &dest); err != nil {
    fmt.Println(err)
    return
} else if len(dest.Error) > 0 {
    fmt.Println(dest.Error)
    return
}

response := dest.Response
// ...

See an example on playground: https://play.golang.com/p/eAhFt99n07k

Upvotes: 3

Related Questions