From f23264c0c5d4c403875bfd7cacec4932f8e403f5 Mon Sep 17 00:00:00 2001 From: Ilia Choly Date: Tue, 12 Dec 2023 15:18:13 -0500 Subject: [PATCH] Handle invalid ChangeEvent APIErrorObject response (#479) --- client.go | 62 +++++++++++++++++++++++++++----------------------- client_test.go | 5 ++++ 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/client.go b/client.go index 967b250b..709a0442 100644 --- a/client.go +++ b/client.go @@ -83,14 +83,37 @@ type APIErrorObject struct { Errors []string `json:"errors,omitempty"` } -// fallbackAPIErrorObject is a shim to solve this issue: -// https://github.com/PagerDuty/go-pagerduty/issues/339 -// -// TODO: remove when PagerDuty engineering confirms bugfix to the REST API -type fallbackAPIErrorObject struct { - Code int `json:"code,omitempty"` - Message string `json:"message,omitempty"` - Errors string `json:"errors,omitempty"` +func unmarshalApiErrorObject(data []byte) (APIErrorObject, error) { + var aeo APIErrorObject + err := json.Unmarshal(data, &aeo) + if err == nil { + return aeo, nil + } + if _, ok := err.(*json.UnmarshalTypeError); !ok { + return aeo, nil + } + // See - https://github.com/PagerDuty/go-pagerduty/issues/339 + // TODO: remove when PagerDuty engineering confirms bugfix to the REST API + var fallback1 struct { + Code int `json:"code,omitempty"` + Message string `json:"message,omitempty"` + Errors string `json:"errors,omitempty"` + } + if json.Unmarshal(data, &fallback1) == nil { + aeo.Code = fallback1.Code + aeo.Message = fallback1.Message + aeo.Errors = []string{fallback1.Errors} + return aeo, nil + } + // See - https://github.com/PagerDuty/go-pagerduty/issues/478 + var fallback2 []string + if json.Unmarshal(data, &fallback2) == nil { + aeo.Message = "none" + aeo.Errors = fallback2 + return aeo, nil + } + // still failed, so return the original error + return aeo, err } // NullAPIErrorObject is a wrapper around the APIErrorObject type. If the Valid @@ -111,28 +134,9 @@ var _ json.Unmarshaler = (*NullAPIErrorObject)(nil) // assert that it satisfies // UnmarshalJSON satisfies encoding/json.Unmarshaler func (n *NullAPIErrorObject) UnmarshalJSON(data []byte) error { - var aeo APIErrorObject - - err := json.Unmarshal(data, &aeo) + aeo, err := unmarshalApiErrorObject(data) if err != nil { - terr, ok := err.(*json.UnmarshalTypeError) - if !ok { - return err - } - - // - // see https://github.com/PagerDuty/go-pagerduty/issues/339 - // - var faeo fallbackAPIErrorObject - - if err := json.Unmarshal(data, &faeo); err != nil { - // still failed, so return the original error - return terr - } - - aeo.Code = faeo.Code - aeo.Message = faeo.Message - aeo.Errors = []string{faeo.Errors} + return err } n.ErrorObject = aeo diff --git a/client_test.go b/client_test.go index f2dced86..e95e4ad9 100644 --- a/client_test.go +++ b/client_test.go @@ -136,6 +136,11 @@ func TestAPIError_Error(t *testing.T) { input: `{"error":{"code": 420, "message": "Enhance Your Calm", "errors":["No Seriously, Enhance Your Calm", "Slow Your Roll", "No, really..."]}}`, want: "HTTP response failed with status code 429, message: Enhance Your Calm (code: 420): No Seriously, Enhance Your Calm (and 2 more errors...)", }, + { + name: "issue_478", + input: `{"error":["links should have at most 50 item(s)"]}`, + want: "HTTP response failed with status code 429, message: none (code: 0): links should have at most 50 item(s)", + }, } for _, tt := range tests {