bugsnag / bugsnag-api-ruby

BugSnag API toolkit for Ruby
Other
21 stars 15 forks source link

Bugsnag::Api::RateLimitExceeded has no metadata on response rate-limit headers #49

Open ohookins opened 9 months ago

ohookins commented 9 months ago

Describe the bug

While using the library to collect metadata about events/errors, due to the volume of requests easily exceeding the rate limits, I hit the rate limits often. The documentation for the API indicates that the responses will have two headers indicating the number of maximum requests per minute, and the time left to make another request within the next rate limiting window. These headers are not present on the Bugsnag::Api::RateLimitExceeded exception, making it hard to adequately handle retries.

Steps to reproduce

  1. Use the bugsnag-api gem.
  2. Make any request via the library enough times.
  3. Receive Bugsnag::Api::RateLimitExceeded exception.
  4. It only has the following methods:
[:detailed_message, :backtrace, :backtrace_locations, :set_backtrace, :cause, :full_message, :message, :exception]

None of these contain rate limiting information.

Environment

Example code snippet

Bugsnag::Api.error_events(project_id, error_id).each do |event|
  begin
    metadata = Bugsnag::Api.event(project_id, event.id).metaData
    pp metadata
  rescue Bugsnag::Api::RateLimitExceeded => e
    puts "Rate limit exceeded, sleeping..."
    sleep 60
    retry
  end
end
Error messages: ``` # ```
clr182 commented 9 months ago

Hi @ohookins Thank you for raising this. There is an item on our product roadmap to look into improving rate limit handling, however I don't have an ETA for when that work will be completed. I'll keep this thread updated with progress 👍

For potential workarounds in the meantime while we work on this, It may also be worth checking out the responses in this issue, which is somewhat similar.

gabrieldeal commented 3 months ago

I worked around the missing API with this hack:

until last_response.rels[:next].nil?
  begin
    last_response = last_response.rels[:next].get
    ...
  rescue Bugsnag::Api::RateLimitExceeded => e
    retry_after = e.instance_variable_get(:@response).response_headers['retry-after']
    sleep retry_after.to_i
  end
end
clr182 commented 2 months ago

Hi @gabrieldeal

Thank you for sharing this additional context. I can pass this to our product team for further evaluation and let you know once our roadmap item has been completed.