( ctx context.Context, globalBackoff *backoff.Backoff, callOpts *github.ListOptions, githubCall func(opts *github.ListOptions) (K, *github.Response, error), aggregator func(K) []T, )
| 89 | } |
| 90 | |
| 91 | func GetPaginatedResult[T any, K any]( |
| 92 | ctx context.Context, |
| 93 | globalBackoff *backoff.Backoff, |
| 94 | callOpts *github.ListOptions, |
| 95 | githubCall func(opts *github.ListOptions) (K, *github.Response, error), |
| 96 | aggregator func(K) []T, |
| 97 | ) ([]T, error) { |
| 98 | |
| 99 | var results []T |
| 100 | retries := 0 |
| 101 | |
| 102 | var back *backoff.Backoff |
| 103 | if globalBackoff != nil { |
| 104 | back = &backoff.Backoff{ |
| 105 | Min: globalBackoff.Min, |
| 106 | Max: globalBackoff.Max, |
| 107 | Jitter: globalBackoff.Jitter, |
| 108 | } |
| 109 | } else { |
| 110 | back = &backoff.Backoff{ |
| 111 | Min: 30 * time.Second, |
| 112 | Max: 30 * time.Minute, |
| 113 | Jitter: true, |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | for { |
| 118 | raw, resp, err := githubCall(callOpts) |
| 119 | |
| 120 | _, ok := err.(*github.RateLimitError) |
| 121 | if ok || resp == nil { |
| 122 | d := back.Duration() |
| 123 | log.Logger.Infof("Hit rate limit, sleeping for %v", d) |
| 124 | time.Sleep(d) |
| 125 | if resp == nil { |
| 126 | retries += 1 |
| 127 | if retries > 10 { |
| 128 | return results, fmt.Errorf( |
| 129 | "Aborting after 5 failed retries", |
| 130 | ) |
| 131 | } |
| 132 | } |
| 133 | continue |
| 134 | } |
| 135 | |
| 136 | retries = 0 |
| 137 | if err != nil && resp != nil { |
| 138 | if resp.StatusCode == 403 { |
| 139 | log.Logger.Debugf( |
| 140 | "It appears the token being used doesn't have access to call %v", |
| 141 | runtime.FuncForPC(reflect.ValueOf(githubCall).Pointer()). |
| 142 | Name(), |
| 143 | ) |
| 144 | log.Logger.Errorf( |
| 145 | "The token used does not have premissions to make this API call", |
| 146 | ) |
| 147 | } else { |
| 148 | log.Logger.Error(err) |
no outgoing calls
no test coverage detected