lib/tretry.rb in tretry-0.0.3 vs lib/tretry.rb in tretry-0.0.4

- old
+ new

@@ -1,11 +1,10 @@ -#A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more. +# A library for doing retries in Ruby with timeouts, analysis of errors, waits between tries and more. class Tretry autoload :Result, "#{__dir__}/tretry/result" - attr_reader :fails - attr_accessor :timeout, :tries, :wait + attr_accessor :error, :errors, :exit, :fails, :interrupt, :return_error, :timeout, :tries, :wait #===Runs a block of code a given amount of times until it succeeds. #===Examples # res = Tretry.try(:tries => 3) do # #something that often fails @@ -16,114 +15,114 @@ def self.try(**args, &block) Tretry.new(**args).try(&block) end def initialize(errors: nil, exit: true, interrupt: true, return_error: nil, timeout: nil, tries: 3, wait: nil) - @errors = errors - @exit = exit - @fails = [] - @interrupt = interrupt + self.errors = errors + self.exit = exit + self.fails = [] + self.interrupt = interrupt @before_retry = [] - @return_error = return_error - @timeout = timeout - @tries = tries - @wait = wait + self.return_error = return_error + self.timeout = timeout + self.tries = tries + self.wait = wait end def before_retry(&block) @before_retry << block end - def try(&block) + def try(&block) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity raise "No block given." unless block + @block = block - @tries.times do |count| + tries.times do |count| @count = count unless first_try? # Sleep for a given amount of time if the 'wait'-argument is given. - sleep(@wait) if @wait + sleep(wait) if wait - call_before_retry(error: @error) - @error = nil + call_before_retry(error: error) + self.error = nil end begin # If a timeout-argument has been given, then run the code through the timeout. - if @timeout + if timeout try_with_timeout else # Else call block normally. @res = @block.call @dobreak = true end - rescue Exception => e + rescue Exception => e # rubocop:disable Lint/RescueException handle_error(e) end if @doraise - if @return_error - @fails << {error: @error} + if return_error + fails << {error: error} + return Tretry::Result.new( - fails: @fails, + fails: fails, error: true ) - else - raise @error end - elsif @error - @fails << {error: @error} + + raise error + elsif error + fails << {error: error} end break if @dobreak end Tretry::Result.new( - fails: @fails, + fails: fails, result: @res, error: false ) end private def try_with_timeout - begin - require "timeout" - Timeout.timeout(@timeout) do - @res = @block.call - @dobreak = true - end - rescue Timeout::Error => e - handle_error(e) + require "timeout" + Timeout.timeout(timeout) do + @res = @block.call + @dobreak = true end + rescue Timeout::Error => e + handle_error(e) end - def handle_error(e) - if e.class == Interrupt - raise e if @interrupt - elsif e.class == SystemExit - raise e if @exit - elsif last_try? || @errors&.include?(e.class) - @doraise = e - elsif @errors&.include?(e.class) + def handle_error(error) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + if error.instance_of?(Interrupt) + raise error if interrupt + elsif error.instance_of?(SystemExit) + raise error if self.exit + elsif last_try? || (errors && !errors.include?(error.class)) + @doraise = error + elsif errors&.include?(error.class) # rubocop:disable Lint/EmptyConditionalBody # Given error was in the :errors-array - do nothing. Maybe later it should be logged and returned in a stats-hash or something? - knj end - @error = e + self.error = error end def call_before_retry(args) @before_retry.each do |before_retry_block| before_retry_block.call(args) end end def last_try? - (@count + 1) >= @tries + (@count + 1) >= tries end def first_try? - @count == 0 + @count.zero? end end