bugsnag-api-ruby icon indicating copy to clipboard operation
bugsnag-api-ruby copied to clipboard

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

Open ohookins opened this issue 2 years ago • 3 comments

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

  • Ruby version: 3.2.2

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:
#<Bugsnag::Api::RateLimitExceeded: GET https://api.bugsnag.com/projects/xxxxevents/xxxx: 429 - >

ohookins avatar Dec 01 '23 00:12 ohookins

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.

clr182 avatar Dec 08 '23 15:12 clr182

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

gabrieldeal avatar Jun 06 '24 00:06 gabrieldeal

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.

clr182 avatar Jun 11 '24 09:06 clr182