summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Hobson2013-11-22 10:09:27 -0800
committerZack Hobson2013-11-22 10:09:27 -0800
commit684ae1d2d0160a36c704dbc87686d1524647aeff (patch)
treea82a66ffe01dfebc799b735d31f6115ba4379d08
parentf99f6b6805a801b2d4bd37d357d0e2d9191c8a5a (diff)
downloadhcl-684ae1d2d0160a36c704dbc87686d1524647aeff.tar.bz2
app: retry on throttle
-rw-r--r--lib/hcl/app.rb4
-rw-r--r--lib/hcl/timesheet_resource.rb9
-rw-r--r--test/app_test.rb15
3 files changed, 26 insertions, 2 deletions
diff --git a/lib/hcl/app.rb b/lib/hcl/app.rb
index ac1b992..4185a67 100644
--- a/lib/hcl/app.rb
+++ b/lib/hcl/app.rb
@@ -61,6 +61,10 @@ module HCl
rescue SocketError => e
STDERR.puts "Connection failed. (#{e.message})"
exit 1
+ rescue TimesheetResource::ThrottleFailure => e
+ STDERR.puts "Too many requests, retrying in #{e.retry_after+5} seconds..."
+ sleep e.retry_after+5
+ run
rescue TimesheetResource::AuthFailure => e
STDERR.puts "Unable to authenticate: #{e}"
request_config
diff --git a/lib/hcl/timesheet_resource.rb b/lib/hcl/timesheet_resource.rb
index 69eeb75..d4624ad 100644
--- a/lib/hcl/timesheet_resource.rb
+++ b/lib/hcl/timesheet_resource.rb
@@ -17,6 +17,13 @@ module HCl
class TimesheetResource
class Failure < StandardError; end
class AuthFailure < StandardError; end
+ class ThrottleFailure < StandardError
+ attr_reader :retry_after
+ def initialize response
+ @retry_after = response.headers['Retry-After'].to_i
+ super "Too many requests! Try again in #{@retry_after} seconds."
+ end
+ end
def self.configure opts = nil
if opts
@@ -68,6 +75,8 @@ module HCl
response.body
when Net::HTTPFound
raise Failure, "Redirected! Perhaps your ssl configuration variable is set incorrectly?"
+ when Net::HTTPServiceUnavailable
+ raise ThrottleFailure, response
when Net::HTTPUnauthorized
raise AuthFailure, "Login failed."
else
diff --git a/test/app_test.rb b/test/app_test.rb
index cbee636..28acba9 100644
--- a/test/app_test.rb
+++ b/test/app_test.rb
@@ -7,11 +7,22 @@ class AppTest < Test::Unit::TestCase
end
def test_command_show
- HCl::DayEntry.expects(:all).returns([HCl::DayEntry.new({
+ HCl::DayEntry.expects(:all).returns [HCl::DayEntry.new(
hours:'2.06',
notes: 'hi world',
project: 'App'
- })])
+ )]
HCl::App.command 'show'
end
+
+ def test_command_retry_on_throttle
+ app = HCl::App.new
+ throttled = states('throttled').starts_as(false)
+ app.expects(:show).
+ raises(HCl::TimesheetResource::ThrottleFailure, stub(headers:{'Retry-After' => 42})).
+ then(throttled.is(true))
+ app.expects(:sleep).with(47).when(throttled.is(true))
+ app.expects(:show).when(throttled.is(true))
+ app.process_args('show').run
+ end
end