Skip to content

Commit 1b37b16

Browse files
committed
Implement retry logic for handling 403 errors in InactiveMemberSearch methods
1 parent 75b9426 commit 1b37b16

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

api/ruby/find-inactive-members/find_inactive_members.rb

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,16 @@ def check_app
161161
end
162162

163163
def check_scopes
164-
info "Scopes: #{@client.scopes.join ','}\n"
164+
scopes = retry_on_403("checking scopes") do
165+
@client.scopes
166+
end
167+
info "Scopes: #{scopes.join ','}\n"
165168
end
166169

167170
def check_rate_limit
168-
rate_limit = @client.rate_limit
171+
rate_limit = retry_on_403("checking rate limit") do
172+
@client.rate_limit
173+
end
169174
info "Rate limit: #{rate_limit.remaining}/#{rate_limit.limit}\n"
170175
info "Rate limit resets at: #{rate_limit.resets_at}\n"
171176
info "Throttling: Limited to #{ThrottleMiddleware::MAX_REQUESTS_PER_HOUR} requests/hour (#{ThrottleMiddleware::MIN_DELAY_SECONDS.round(2)}s min delay)\n"
@@ -200,6 +205,39 @@ def info(message)
200205
$stdout.print message
201206
end
202207

208+
# Helper method to handle 403 errors with retry logic
209+
def retry_on_403(description, max_retries = 3)
210+
retries = 0
211+
212+
loop do
213+
begin
214+
return yield
215+
rescue Octokit::Forbidden => e
216+
retries += 1
217+
info "⚠️ 403 Forbidden error occurred while #{description}\n"
218+
219+
if retries <= max_retries
220+
info "🔄 Waiting 5 seconds before retry #{retries}/#{max_retries}...\n"
221+
sleep(5)
222+
next
223+
else
224+
info "❌ Failed after #{max_retries} retries for #{description}\n"
225+
print "🤔 Do you want to continue retrying? (Y/N): "
226+
response = gets.chomp.upcase
227+
228+
if response == 'Y'
229+
info "🔄 Continuing with another #{max_retries} retry attempts...\n"
230+
retries = 0 # Reset retry counter
231+
next
232+
else
233+
info "🛑 User chose to exit. Stopping application.\n"
234+
exit(1)
235+
end
236+
end
237+
end
238+
end
239+
end
240+
203241
# Helper method to manually paginate requests with proper throttling
204242
def paginated_request(method, *args, **kwargs)
205243
results = []
@@ -210,11 +248,13 @@ def paginated_request(method, *args, **kwargs)
210248
# Merge pagination parameters with existing kwargs
211249
page_kwargs = kwargs.merge(page: page, per_page: per_page)
212250

213-
# Handle different method signatures
214-
if args.empty?
215-
response = @client.send(method, page_kwargs)
216-
else
217-
response = @client.send(method, *args, page_kwargs)
251+
# Handle different method signatures with 403 retry logic
252+
response = retry_on_403("fetching #{method} page #{page}") do
253+
if args.empty?
254+
@client.send(method, page_kwargs)
255+
else
256+
@client.send(method, *args, page_kwargs)
257+
end
218258
end
219259

220260
break if response.empty?
@@ -230,7 +270,11 @@ def paginated_request(method, *args, **kwargs)
230270
end
231271

232272
def member_email(login)
233-
@email ? @client.user(login)[:email] : ""
273+
return "" unless @email
274+
275+
retry_on_403("fetching email for user #{login}") do
276+
@client.user(login)[:email]
277+
end
234278
end
235279

236280
def organization_members

0 commit comments

Comments
 (0)