Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow retrying based on the "cause" exception #18

Open
jeremyhaile opened this issue Oct 15, 2015 · 5 comments
Open

Allow retrying based on the "cause" exception #18

jeremyhaile opened this issue Oct 15, 2015 · 5 comments

Comments

@jeremyhaile
Copy link

Sometimes APIs wrap exceptions so that the top-level exception by itself isn't enough to determine whether or not to retry the code. However, the cause exception could be used to determine that the code should be retried.

Currently retriable only allows retrying based on the raised exception, and doesn't provide a way to examine the caused exception.

Here is an example. In this case, we want to retry based on the RootCauseError, but since the API we're using actually raises DemoError, the code block doesn't get retried.

class RootCauseError < StandardError; end
class DemoError < StandardError; end
begin
  i = 0
  Retriable.retriable on: [RootCauseError] do
    begin
      puts "Try #{i += 1}..."
      raise RootCauseError.new("BUT THIS IS THE CAUSE")
    rescue => e
      raise DemoError.new("RETRIABLE ONLY LOOKS AT THIS")
    end
  end
rescue => e
  puts "Raised error: #{e.inspect}"
  puts "Cause error: #{e.cause.inspect}"
end

Two ideas for solving this:

  1. Make retriable examine the cause of errors as well as the errors itself. This could either only go one level deep, or recurse...perhaps with a limit on recursion depth.
  2. Allow passing in a proc or method to the on option that would then be invoked with the error and would return true or false to determine if the error should be retried. This proc could then examine the error class and its cause, and would have the benefit of also supporting lots of advanced cases that are not possible right now.
@kamui
Copy link
Owner

kamui commented Mar 2, 2016

Sorry I never replied to this ticket. I wanted to think about solutions for this and see if other users had similar issues. I haven't come to any conclusions, but wanted to comment to let you know I've read this issue.

@apurvis
Copy link
Contributor

apurvis commented Jan 9, 2017

you can sort of do this with a regex in the :on parameter? often the "cause" gets stringified into the message of the actually raised parameter - that's a common pattern i've seen with Faraday, for instance.

other than that i don't see any way to deal with the example posted; Retriable can't reach into the block and figure out that someone rescued one exception and chose to raise a different type of exception.

@apurvis
Copy link
Contributor

apurvis commented Feb 15, 2017

re-reading my comment, i actually had no idea about the Exception#cause feature in ruby 2.1. This issue makes a lot more sense to me now and seems like it might be worth implementing, though it will require some hackery depending on the ruby version.

@rafaelsales
Copy link

It would be nice if the on accepted a block and retry only if the result of the block is true

@apurvis
Copy link
Contributor

apurvis commented Aug 31, 2017

@rafaelsales i think that would be pretty straightforward to implement if you wanted to try to open a PR, though i'm not sure it's that relevant to this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants