From d0447e51dad621b32383ccb09b68a16ff6d956b0 Mon Sep 17 00:00:00 2001 From: Mark Mulder Date: Wed, 6 Sep 2017 13:48:33 +0200 Subject: [PATCH 1/2] Add TooManyRequests error for 429 This will make it a bit easier to follow, instead of people having to remember that 429 is because of rate limiting. https://httpstatuses.com/429 --- lib/help_scout.rb | 4 ++++ spec/helpscout_spec.rb | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/lib/help_scout.rb b/lib/help_scout.rb index 3246c1a..524f6b7 100644 --- a/lib/help_scout.rb +++ b/lib/help_scout.rb @@ -5,6 +5,7 @@ class HelpScout class ValidationError < StandardError; end class NotImplementedError < StandardError; end class NotFoundError < StandardError; end + class TooManyRequestsError < StandardError; end class InternalServerError < StandardError; end # Status codes used by Help Scout, not all are implemented in this gem yet. @@ -14,6 +15,7 @@ class InternalServerError < StandardError; end HTTP_NO_CONTENT = 204 HTTP_BAD_REQUEST = 400 HTTP_NOT_FOUND = 404 + HTTP_TOO_MANY_REQUESTS = 429 HTTP_INTERNAL_SERVER_ERROR = 500 attr_accessor :last_response @@ -206,6 +208,8 @@ def request(method, path, options) raise NotFoundError when HTTP_INTERNAL_SERVER_ERROR raise InternalServerError + when HTTP_TOO_MANY_REQUESTS + raise TooManyRequestsError else raise NotImplementedError, "Help Scout returned something that is not implemented by the help_scout gem yet: #{@last_response.code}: #{@last_response.parsed_response["message"] if @last_response.parsed_response}" end diff --git a/spec/helpscout_spec.rb b/spec/helpscout_spec.rb index b8a0c85..abad7bb 100644 --- a/spec/helpscout_spec.rb +++ b/spec/helpscout_spec.rb @@ -144,4 +144,13 @@ expect(req).to have_been_requested end end + + describe 'general rate limiting error' do + it 'returns TooManyRequestsError' do + url = 'https://api.helpscout.net/v1/conversations/1337.json' + stub_request(:get, url).to_return(status: 429) + + expect { client.get_conversation(1337) }.to raise_error(HelpScout::TooManyRequestsError) + end + end end From 0e1d86dbb9b83bbbb4ffb6b46bb204ac7736dec4 Mon Sep 17 00:00:00 2001 From: Mark Mulder Date: Thu, 7 Sep 2017 15:05:48 +0200 Subject: [PATCH 2/2] Add message about when we can retry again --- lib/help_scout.rb | 4 +++- spec/helpscout_spec.rb | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/help_scout.rb b/lib/help_scout.rb index 524f6b7..8fb5f9b 100644 --- a/lib/help_scout.rb +++ b/lib/help_scout.rb @@ -209,7 +209,9 @@ def request(method, path, options) when HTTP_INTERNAL_SERVER_ERROR raise InternalServerError when HTTP_TOO_MANY_REQUESTS - raise TooManyRequestsError + retry_after = last_response.headers["Retry-After"] + error_message = "Rate limit of 200 RPM or 12 POST/PUT/DELETE requests per 5 seconds reached. Next request possible in #{retry_after} seconds." + raise TooManyRequestsError, error_message else raise NotImplementedError, "Help Scout returned something that is not implemented by the help_scout gem yet: #{@last_response.code}: #{@last_response.parsed_response["message"] if @last_response.parsed_response}" end diff --git a/spec/helpscout_spec.rb b/spec/helpscout_spec.rb index abad7bb..965214d 100644 --- a/spec/helpscout_spec.rb +++ b/spec/helpscout_spec.rb @@ -148,9 +148,16 @@ describe 'general rate limiting error' do it 'returns TooManyRequestsError' do url = 'https://api.helpscout.net/v1/conversations/1337.json' - stub_request(:get, url).to_return(status: 429) + stub_request(:get, url). + to_return( + status: 429, + headers: { + retry_after: '10', + } + ) - expect { client.get_conversation(1337) }.to raise_error(HelpScout::TooManyRequestsError) + error_message = "Rate limit of 200 RPM or 12 POST/PUT/DELETE requests per 5 seconds reached. Next request possible in 10 seconds." + expect { client.get_conversation(1337) }.to raise_error(HelpScout::TooManyRequestsError, error_message) end end end