diff --git a/github/github.go b/github/github.go index 42b6382c6da..91af5aa665f 100644 --- a/github/github.go +++ b/github/github.go @@ -1363,9 +1363,13 @@ type AbuseRateLimitError struct { } func (r *AbuseRateLimitError) Error() string { - return fmt.Sprintf("%v %v: %v %v", + retryInfo := "" + if r.RetryAfter != nil && *r.RetryAfter > 0 { + retryInfo = fmt.Sprintf(" [retry after %v]", r.RetryAfter.Round(time.Second)) + } + return fmt.Sprintf("%v %v: %v %v%v", r.Response.Request.Method, sanitizeURL(r.Response.Request.URL), - r.Response.StatusCode, r.Message) + r.Response.StatusCode, r.Message, retryInfo) } // Is returns whether the provided error equals this error. diff --git a/github/github_test.go b/github/github_test.go index de67ed75661..cecc72b6ed4 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -3277,16 +3277,51 @@ func TestAbuseRateLimitError(t *testing.T) { t.Fatal(err) } - r := &AbuseRateLimitError{ - Response: &http.Response{ - Request: &http.Request{Method: "PUT", URL: u}, - StatusCode: http.StatusTooManyRequests, - }, - Message: "", - } - if got, want := r.Error(), "PUT https://example.com: 429 "; got != want { - t.Errorf("AbuseRateLimitError = %q, want %q", got, want) - } + t.Run("nil RetryAfter", func(t *testing.T) { + t.Parallel() + r := &AbuseRateLimitError{ + Response: &http.Response{ + Request: &http.Request{Method: "PUT", URL: u}, + StatusCode: http.StatusTooManyRequests, + }, + Message: "", + } + if got, want := r.Error(), "PUT https://example.com: 429 "; got != want { + t.Errorf("AbuseRateLimitError = %q, want %q", got, want) + } + }) + + t.Run("with RetryAfter", func(t *testing.T) { + t.Parallel() + d := 60 * time.Second + r := &AbuseRateLimitError{ + Response: &http.Response{ + Request: &http.Request{Method: "GET", URL: u}, + StatusCode: http.StatusForbidden, + }, + Message: "rate limited", + RetryAfter: &d, + } + if got, want := r.Error(), "GET https://example.com: 403 rate limited [retry after 1m0s]"; got != want { + t.Errorf("AbuseRateLimitError = %q, want %q", got, want) + } + }) + + t.Run("zero RetryAfter", func(t *testing.T) { + t.Parallel() + d := 0 * time.Second + r := &AbuseRateLimitError{ + Response: &http.Response{ + Request: &http.Request{Method: "POST", URL: u}, + StatusCode: http.StatusForbidden, + }, + Message: "rate limited", + RetryAfter: &d, + } + if got, want := r.Error(), "POST https://example.com: 403 rate limited"; got != want { + t.Errorf("AbuseRateLimitError = %q, want %q", got, want) + } + }) } func TestBareDo_returnsOpenBody(t *testing.T) {