Skip to content

Commit 231da32

Browse files
caarlos0gmlewis
authored andcommitted
Deal with 202 Accepted Status Code
Fixes #486. Closes #488. Change-Id: I31ff003552dbffaca78c740b89d54150b81c525c
1 parent a77ccc9 commit 231da32

File tree

5 files changed

+77
-11
lines changed

5 files changed

+77
-11
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,23 @@ if _, ok := err.(*github.RateLimitError); ok {
9999
Learn more about GitHub rate limiting at
100100
http://developer.github.com/v3/#rate-limiting.
101101

102+
### Accepted Status ###
103+
104+
Some endpoints may return a 202 Accepted status code, meaning that the
105+
information required is not yet ready and was scheduled to be gathered on
106+
the GitHub side. Methods known to behave like this are documented specifying
107+
this behavior.
108+
109+
To detect this condition of error, you can check if its type is
110+
`*github.AcceptedError`:
111+
112+
```go
113+
stats, _, err := client.Repositories.ListContributorsStats(org, repo)
114+
if _, ok := err.(*github.AcceptedError); ok {
115+
log.Println("scheduled on GitHub side")
116+
}
117+
```
118+
102119
### Conditional Requests ###
103120

104121
The GitHub API has good support for conditional requests which will help

github/doc.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ To detect an API rate limit error, you can check if its type is *github.RateLimi
8686
Learn more about GitHub rate limiting at
8787
http://developer.github.com/v3/#rate-limiting.
8888
89+
Accepted Status
90+
91+
Some endpoints may return a 202 Accepted status code, meaning that the
92+
information required is not yet ready and was scheduled to be gathered on
93+
the GitHub side. Methods known to behave like this are documented specifying
94+
this behavior.
95+
96+
To detect this condition of error, you can check if its type is
97+
*github.AcceptedError:
98+
99+
stats, _, err := client.Repositories.ListContributorsStats(org, repo)
100+
if _, ok := err.(*github.AcceptedError); ok {
101+
log.Println("scheduled on GitHub side")
102+
}
103+
89104
Conditional Requests
90105
91106
The GitHub API has good support for conditional requests which will help

github/github.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,18 @@ func (r *RateLimitError) Error() string {
501501
r.Response.StatusCode, r.Message, r.Rate.Reset.Time.Sub(time.Now()))
502502
}
503503

504+
// AcceptedError occurs when GitHub returns 202 Accepted response with an
505+
// empty body, which means a job was scheduled on the GitHub side to process
506+
// the information needed and cache it.
507+
// Technically, 202 Accepted is not a real error, it's just used to
508+
// indicate that results are not ready yet, but should be available soon.
509+
// The request can be repeated after some time.
510+
type AcceptedError struct{}
511+
512+
func (*AcceptedError) Error() string {
513+
return "job scheduled on GitHub side; try again later"
514+
}
515+
504516
// AbuseRateLimitError occurs when GitHub returns 403 Forbidden response with the
505517
// "documentation_url" field value equal to "https://developer.github.com/v3#abuse-rate-limits".
506518
type AbuseRateLimitError struct {
@@ -564,14 +576,19 @@ func (e *Error) Error() string {
564576
}
565577

566578
// CheckResponse checks the API response for errors, and returns them if
567-
// present. A response is considered an error if it has a status code outside
568-
// the 200 range. API error responses are expected to have either no response
579+
// present. A response is considered an error if it has a status code outside
580+
// the 200 range or equal to 202 Accepted.
581+
// API error responses are expected to have either no response
569582
// body, or a JSON response body that maps to ErrorResponse. Any other
570583
// response body will be silently ignored.
571584
//
572585
// The error type will be *RateLimitError for rate limit exceeded errors,
586+
// *AcceptedError for 202 Accepted status codes,
573587
// and *TwoFactorAuthError for two-factor authentication errors.
574588
func CheckResponse(r *http.Response) error {
589+
if r.StatusCode == http.StatusAccepted {
590+
return &AcceptedError{}
591+
}
575592
if c := r.StatusCode; 200 <= c && c <= 299 {
576593
return nil
577594
}

github/repos_forks.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ type RepositoryCreateForkOptions struct {
5050

5151
// CreateFork creates a fork of the specified repository.
5252
//
53+
// This method might return an *AcceptedError and a status code of
54+
// 202. This is because this is the status that GitHub returns to signify that
55+
// it is now computing creating the fork in a background task.
56+
// A follow up request, after a delay of a second or so, should result
57+
// in a successful request.
58+
//
5359
// GitHub API docs: https://developer.github.com/v3/repos/forks/#create-a-fork
5460
func (s *RepositoriesService) CreateFork(owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) {
5561
u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)

github/repos_stats.go

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ func (w WeeklyStats) String() string {
3939
// deletions and commit counts.
4040
//
4141
// If this is the first time these statistics are requested for the given
42-
// repository, this method will return a non-nil error and a status code of
43-
// 202. This is because this is the status that github returns to signify that
42+
// repository, this method will return an *AcceptedError and a status code of
43+
// 202. This is because this is the status that GitHub returns to signify that
4444
// it is now computing the requested statistics. A follow up request, after a
4545
// delay of a second or so, should result in a successful request.
4646
//
@@ -78,8 +78,8 @@ func (w WeeklyCommitActivity) String() string {
7878
// starting on Sunday.
7979
//
8080
// If this is the first time these statistics are requested for the given
81-
// repository, this method will return a non-nil error and a status code of
82-
// 202. This is because this is the status that github returns to signify that
81+
// repository, this method will return an *AcceptedError and a status code of
82+
// 202. This is because this is the status that GitHub returns to signify that
8383
// it is now computing the requested statistics. A follow up request, after a
8484
// delay of a second or so, should result in a successful request.
8585
//
@@ -104,6 +104,12 @@ func (s *RepositoriesService) ListCommitActivity(owner, repo string) ([]*WeeklyC
104104
// deletions pushed to a repository. Returned WeeklyStats will contain
105105
// additions and deletions, but not total commits.
106106
//
107+
// If this is the first time these statistics are requested for the given
108+
// repository, this method will return an *AcceptedError and a status code of
109+
// 202. This is because this is the status that GitHub returns to signify that
110+
// it is now computing the requested statistics. A follow up request, after a
111+
// delay of a second or so, should result in a successful request.
112+
//
107113
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#code-frequency
108114
func (s *RepositoriesService) ListCodeFrequency(owner, repo string) ([]*WeeklyStats, *Response, error) {
109115
u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo)
@@ -152,11 +158,10 @@ func (r RepositoryParticipation) String() string {
152158
// The array order is oldest week (index 0) to most recent week.
153159
//
154160
// If this is the first time these statistics are requested for the given
155-
// repository, this method will return a non-nil error and a status code
156-
// of 202. This is because this is the status that github returns to
157-
// signify that it is now computing the requested statistics. A follow
158-
// up request, after a delay of a second or so, should result in a
159-
// successful request.
161+
// repository, this method will return an *AcceptedError and a status code of
162+
// 202. This is because this is the status that GitHub returns to signify that
163+
// it is now computing the requested statistics. A follow up request, after a
164+
// delay of a second or so, should result in a successful request.
160165
//
161166
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#participation
162167
func (s *RepositoriesService) ListParticipation(owner, repo string) (*RepositoryParticipation, *Response, error) {
@@ -185,6 +190,12 @@ type PunchCard struct {
185190

186191
// ListPunchCard returns the number of commits per hour in each day.
187192
//
193+
// If this is the first time these statistics are requested for the given
194+
// repository, this method will return an *AcceptedError and a status code of
195+
// 202. This is because this is the status that GitHub returns to signify that
196+
// it is now computing the requested statistics. A follow up request, after a
197+
// delay of a second or so, should result in a successful request.
198+
//
188199
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#punch-card
189200
func (s *RepositoriesService) ListPunchCard(owner, repo string) ([]*PunchCard, *Response, error) {
190201
u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo)

0 commit comments

Comments
 (0)