Class: Faraday::Retry::Middleware
- Inherits:
-
Middleware
- Object
- Middleware
- Faraday::Retry::Middleware
- Defined in:
- lib/faraday/retry/middleware.rb
Overview
This class provides the main implementation for your middleware. Your middleware can implement any of the following methods:
-
on_request - called when the request is being prepared
-
on_complete - called when the response is being processed
Optionally, you can also override the following methods from Faraday::Middleware
-
initialize(app, options = {}) - the initializer method
-
call(env) - the main middleware invocation method. This already calls on_request and on_complete, so you normally don’t need to override it. You may need to in case you need to “wrap” the request or need more control (see “retry” middleware: github.com/lostisland/faraday/blob/main/lib/faraday/request/retry.rb#L142). IMPORTANT: Remember to call ‘@app.call(env)` or `super` to not interrupt the middleware chain!
Defined Under Namespace
Classes: Options
Constant Summary collapse
- DEFAULT_EXCEPTIONS =
[ Errno::ETIMEDOUT, 'Timeout::Error', Faraday::TimeoutError, Faraday::RetriableResponse ].freeze
- IDEMPOTENT_METHODS =
%i[delete get head options put].freeze
Instance Method Summary collapse
-
#build_exception_matcher(exceptions) ⇒ Module
private
An exception matcher for the rescue clause can usually be any object that responds to ‘===`, but for Ruby 1.8 it has to be a Class or Module.
- #calculate_sleep_amount(retries, env) ⇒ Object
- #call(env) ⇒ Object
-
#initialize(app, options = nil) ⇒ Middleware
constructor
A new instance of Middleware.
Constructor Details
#initialize(app, options = nil) ⇒ Middleware
Returns a new instance of Middleware.
127 128 129 130 131 |
# File 'lib/faraday/retry/middleware.rb', line 127 def initialize(app, = nil) super(app) @options = Options.from() @errmatch = build_exception_matcher(@options.exceptions) end |
Instance Method Details
#build_exception_matcher(exceptions) ⇒ Module
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
An exception matcher for the rescue clause can usually be any object that responds to ‘===`, but for Ruby 1.8 it has to be a Class or Module.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/faraday/retry/middleware.rb', line 185 def build_exception_matcher(exceptions) matcher = Module.new ( class << matcher self end).class_eval do define_method(:===) do |error| exceptions.any? do |ex| if ex.is_a? Module error.is_a? ex else Object.const_defined?(ex.to_s) && error.is_a?(Object.const_get(ex.to_s)) end end end end matcher end |
#calculate_sleep_amount(retries, env) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/faraday/retry/middleware.rb', line 133 def calculate_sleep_amount(retries, env) retry_after = [calculate_retry_after(env), calculate_rate_limit_reset(env)].compact.max retry_interval = calculate_retry_interval(retries) return if retry_after && retry_after > @options.max_interval if retry_after && retry_after >= retry_interval retry_after else retry_interval end end |
#call(env) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/faraday/retry/middleware.rb', line 147 def call(env) retries = @options.max request_body = env[:body] begin # after failure env[:body] is set to the response body env[:body] = request_body @app.call(env).tap do |resp| raise Faraday::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status) end rescue @errmatch => e if retries.positive? && retry_request?(env, e) retries -= 1 rewind_files(request_body) if (sleep_amount = calculate_sleep_amount(retries + 1, env)) @options.retry_block.call( env: env, options: @options, retry_count: @options.max - (retries + 1), exception: e, will_retry_in: sleep_amount ) sleep sleep_amount retry end end raise unless e.is_a?(Faraday::RetriableResponse) e.response end end |