Skip to content

Commit

Permalink
Merge pull request #147 from monzo/add-metadata-on-decode-failure
Browse files Browse the repository at this point in the history
Include more information in errors about what we failed to decode.
  • Loading branch information
cstorey-monzo authored Apr 27, 2022
2 parents deca284 + ece51a6 commit 2e7ad09
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,39 +152,53 @@ func (r *Response) Decode(v interface{}) error {
return r.Error
}

contentType := r.Header.Get("Content-Type")

params := map[string]string{
"response_content_type": contentType,
}

switch m := v.(type) {
// If we have a proto message, unmarshal it as JSON, so we don't break e.g. timestamp encoding or enums.
// This presents a bit of a backwards compatibility issue, though only for those who have been using
// proto.Message incorrectly (without encoding/protojson) with Typhon.
case proto.Message:
switch r.Header.Get("Content-Type") {
params["response_object_type"] = "protobuf"

switch contentType {
case "application/octet-stream",
"application/x-google-protobuf",
"application/protobuf",
"application/x-protobuf":

err = proto.Unmarshal(b, m)
default:

err = protojson.Unmarshal(b, m)
}

// If we have a legacy protobuf message, decode as protobuf if that's signalled, but use standard JSON otherwise.
// This is against Google's recommendations, but also doesn't break things for active users of Typhon.
// Upgrade to google.golang.org/protobuf/proto.Message as soon as possible.
case legacyproto.Message:
switch r.Header.Get("Content-Type") {
params["response_object_type"] = "legacyproto"
switch contentType {
case "application/octet-stream",
"application/x-google-protobuf",
"application/protobuf",
"application/x-protobuf":

err = legacyproto.Unmarshal(b, m)
default:
err = json.Unmarshal(b, m)
}
default:
params["response_object_type"] = "json"

err = json.Unmarshal(b, v)
}

err = terrors.WrapWithCode(err, nil, terrors.ErrBadResponse)
err = terrors.WrapWithCode(err, params, terrors.ErrBadResponse)
if err != nil {
r.Error = err
}
Expand Down

0 comments on commit 2e7ad09

Please sign in to comment.