Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update APIError.Error() to provide more helpful error messages #334

Merged
merged 1 commit into from
Oct 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,40 @@ func (a APIError) Error() string {
return fmt.Sprintf("HTTP response failed with status code %d and no JSON error object was present", a.StatusCode)
}

if len(a.APIError.ErrorObject.Errors) == 0 {
return fmt.Sprintf(
"HTTP response failed with status code %d, message: %s (code: %d)",
a.StatusCode, a.APIError.ErrorObject.Message, a.APIError.ErrorObject.Code,
)
}

return fmt.Sprintf(
"HTTP response failed with status code %d, message: %s (code: %d)",
a.StatusCode, a.APIError.ErrorObject.Message, a.APIError.ErrorObject.Code,
"HTTP response failed with status code %d, message: %s (code: %d): %s",
a.StatusCode,
a.APIError.ErrorObject.Message,
a.APIError.ErrorObject.Code,
apiErrorsDetailString(a.APIError.ErrorObject.Errors),
)
}

func apiErrorsDetailString(errs []string) string {
switch n := len(errs); n {
case 0:
panic("errs slice is empty")

case 1:
return errs[0]

default:
e := "error"
if n > 2 {
e += "s"
}

return fmt.Sprintf("%s (and %d more %s...)", errs[0], n-1, e)
}
}

// RateLimited returns whether the response had a status of 429, and as such the
// client is rate limited. The PagerDuty rate limits should reset once per
// minute, and for the REST API they are an account-wide rate limit (not per
Expand Down
47 changes: 35 additions & 12 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,44 @@ func TestGetBasePrefix(t *testing.T) {
}

func TestAPIError_Error(t *testing.T) {
const jsonBody = `{"error":{"code": 420, "message": "Enhance Your Calm", "errors":["Enhance Your Calm", "Slow Your Roll"]}}`

var a APIError

if err := json.Unmarshal([]byte(jsonBody), &a); err != nil {
t.Fatalf("failed to unmarshal JSON: %s", err)
}
t.Run("json_tests", func(t *testing.T) {
tests := []struct {
name string
input string
want string
}{
{
name: "one_error",
input: `{"error":{"code": 420, "message": "Enhance Your Calm", "errors":["No Seriously, Enhance Your Calm"]}}`,
want: "HTTP response failed with status code 429, message: Enhance Your Calm (code: 420): No Seriously, Enhance Your Calm",
},
{
name: "two_error",
input: `{"error":{"code": 420, "message": "Enhance Your Calm", "errors":["No Seriously, Enhance Your Calm", "Slow Your Roll"]}}`,
want: "HTTP response failed with status code 429, message: Enhance Your Calm (code: 420): No Seriously, Enhance Your Calm (and 1 more error...)",
},
{
name: "three_error",
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...)",
},
}

a.StatusCode = 429
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var a APIError
if err := json.Unmarshal([]byte(tt.input), &a); err != nil {
t.Fatalf("failed to unmarshal JSON: %s", err)
}

const want = "HTTP response failed with status code 429, message: Enhance Your Calm (code: 420)"
a.StatusCode = 429

if got := a.Error(); got != want {
t.Errorf("a.Error() = %q, want %q", got, want)
}
if got := a.Error(); got != tt.want {
t.Errorf("a.Error() = %q, want %q", got, tt.want)
}
})
}
})

tests := []struct {
name string
Expand Down