Skip to content

Commit 2bed074

Browse files
committed
Add auto retry logic for auth expiry separate from normal failure retry
1 parent bfa5225 commit 2bed074

File tree

3 files changed

+34
-18
lines changed

3 files changed

+34
-18
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ in the credentials. Detailed instructions on how to enable delegation for your d
114114

115115
The API client can automatically retry requests for recoverable errors. To enable retries, set the `client.retries` property to
116116
the number of additional attempts. To avoid flooding servers, retries invovle a 1 second delay that increases on each subsequent retry.
117+
In the case of authentication token expiry, the API client will attempt to refresh the token and retry the failed operation - this
118+
is a specific exception to the retry rules.
117119

118120
The default value for retries is 0, but will be enabled by default in future releases.
119121

lib/google/api_client.rb

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -596,25 +596,34 @@ def execute!(*params)
596596

597597
Retriable.retriable :tries => tries,
598598
:on => [TransmissionError],
599-
:on_retry => client_error_handler(request.authorization),
600599
:interval => lambda {|attempts| (2 ** attempts) + rand} do
601-
result = request.send(connection, true)
602-
603-
case result.status
604-
when 200...300
605-
result
606-
when 301, 302, 303, 307
607-
request = generate_request(request.to_hash.merge({
608-
:uri => result.headers['location'],
609-
:api_method => nil
610-
}))
611-
raise RedirectError.new(result.headers['location'], result)
612-
when 400...500
613-
raise ClientError.new(result.error_message || "A client error has occurred", result)
614-
when 500...600
615-
raise ServerError.new(result.error_message || "A server error has occurred", result)
616-
else
617-
raise TransmissionError.new(result.error_message || "A transmission error has occurred", result)
600+
# This 2nd level retriable only catches auth errors, and supports 1 retry, which allows
601+
# auth to be re-attempted without having to retry all sorts of other failures like
602+
# NotFound, etc
603+
Retriable.retriable :tries => 2,
604+
:on => [AuthorizationError],
605+
:on_retry => client_error_handler(request.authorization),
606+
:interval => lambda {|attempts| (2 ** attempts) + rand} do
607+
result = request.send(connection, true)
608+
609+
case result.status
610+
when 200...300
611+
result
612+
when 301, 302, 303, 307
613+
request = generate_request(request.to_hash.merge({
614+
:uri => result.headers['location'],
615+
:api_method => nil
616+
}))
617+
raise RedirectError.new(result.headers['location'], result)
618+
when 401
619+
raise AuthorizationError.new(result.error_message || 'Invalid/Expired Authentication', result)
620+
when 400, 402...500
621+
raise ClientError.new(result.error_message || "A client error has occurred", result)
622+
when 500...600
623+
raise ServerError.new(result.error_message || "A server error has occurred", result)
624+
else
625+
raise TransmissionError.new(result.error_message || "A transmission error has occurred", result)
626+
end
618627
end
619628
end
620629
end

lib/google/api_client/errors.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class ValidationError < StandardError
4343
class ClientError < TransmissionError
4444
end
4545

46+
##
47+
# A 401 HTTP error occurred.
48+
class AuthorizationError < ClientError
49+
end
50+
4651
##
4752
# A 5xx class HTTP error occurred.
4853
class ServerError < TransmissionError

0 commit comments

Comments
 (0)