-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add context with rate limit struct for Octokit::TooManyRequests and Octokit:: AbuseDetected errors #1270
Add context with rate limit struct for Octokit::TooManyRequests and Octokit:: AbuseDetected errors #1270
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Just a small change request.
Thanks @tarebyte for merging this 😄 I have another proposition that I have been using for my personal projects and work, custom pagination for Octokit Let me know if this also seems worth implementing, I will open relevant issues and PR. Pagination methodsdef should_fetch_more?(page_limit, page_iterated)
page_limit.nil? || page_iterated < page_limit.to_i
end
def can_fetch_more?(last_response)
last_response.rels[:next].present? && @octokit_client.rate_limit.remaining > 0
end
def iterate_pagination(opts = {}, result)
page_limit = opts[:page_limit]
page_iterated = 1
last_response = @octokit_client.last_response
record_limit = opts[:item_limit]
while should_fetch_more?(page_limit, page_iterated) && can_fetch_more?(last_response)
last_response = last_response.rels[:next].get
if result.is_a?(Sawyer::Resource)
result.items += result.is_a?(Array) ? last_response.data : last_response.data.items
else
result += result.is_a?(Array) ? last_response.data : last_response.data.items
end
page_iterated += 1
return limit_result_count(result, record_limit.to_i) if record_limit && result.count >= record_limit.to_i
end
record_limit ? limit_result_count(result, record_limit.to_i) : result
end so any utility function can be passed as proc to def execute(opts = {}, &block)
iterate_pagination(opts, yield)
end def find_users(search_text = '', opts = {})
execute(opts) { @octokit_client.search_users(search_text).items }
end and can be used as find_users("user_name", {sort: :indexed, order: :desc, page_limit: 1}) we can clean internal keys as well INTERNAL_OPTS_KEYS = [:page_limit, :item_limit]
def clean_opts(opts)
opts.except(*INTERNAL_OPTS_KEYS)
end for methods that are parsed by octokit for equivalent parameters |
@jatindhankhar mind opening another issue? It's hard to track requests at the end of a merged PR. |
This adds the
context
attribute toOctokit:: Error
for much smoother handling of exception likeOctokit::TooManyRequests
andOctokit:: AbuseDetected
, so that clients consuming them can use the values specified for better retries.Can be consumed like this
Specifically useful when using with background processors like
sidekiq
The idea is to have meaningful context for all types of errors depending upon the type of error.