class Faraday::BetterRetry

Catches exceptions and retries each request a limited number of times.

By default, it retries 2 times and handles only timeout exceptions. It can be configured with an arbitrary number of retries, a list of exceptions to handle an a retry interval.

Examples

Faraday.new do |conn|
  conn.request :retry, max: 2, interval: 0.05,
                       exceptions: [CustomException, 'Timeout::Error']
  conn.adapter ...
end

Public Class Methods

new(app, options = {}) click to toggle source

Public: Initialize middleware

Options: max - Maximum number of retries (default: 2). interval - Pause in seconds between retries (default: 0). exceptions - The list of exceptions to handle. Exceptions can be

given as Class, Module, or String. (default:
[Errno::ETIMEDOUT, Timeout::Error, Error::TimeoutError])
Calls superclass method
# File lib/faraday/better_retry.rb, line 50
def initialize(app, options = {})
  super(app)
  @options = Options.new(options)
  @errmatch = build_exception_matcher(@options.exceptions)
  @logger = options[:logger]
end

Public Instance Methods

build_exception_matcher(exceptions) click to toggle source

Private: construct an exception matcher object.

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.

# File lib/faraday/better_retry.rb, line 79
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 then error.is_a? ex
        else error.class.to_s == ex.to_s
        end
      end
    end
  end
  matcher
end
call(env) click to toggle source
# File lib/faraday/better_retry.rb, line 57
def call(env)
  env[:retries] = retries = @options.max
  begin
    @app.call(env)
  rescue @errmatch => e
    if retries > 0
      if @logger
        @logger.warn("Retrying Parse Error #{e.inspect} on request #{env[:url].to_s} #{env[:body].inspect} response #{env[:response].inspect}")
      end
      retries -= 1
      env[:retries] = retries
      sleep @options.interval if @options.interval > 0
      retry
    end
    raise
  end
end