ElixirRetry icon indicating copy to clipboard operation
ElixirRetry copied to clipboard

Specify only _some_ errors to be retried.

Open rafal0p opened this issue 3 years ago • 2 comments

Let's assume that we have a function like that:

 @spec foo() ::
         :ok
         | {:error, :some_retryable_reason}
         | {:error, :other_retryable_reason}
         | {:error, :some_non_retryable_reason}
         | {:error, :other_non_retryable_reason}
 def foo() do
   ...
 end

What I'd like to express is roughly this:

retry with: linear_backoff(50, 1) |> take(5),
      rescue_only: [
        {:error, :some_retryable_reason},
        {:error, :other_retryable_reason}
      ] do
  foo()
after
  _ -> :ok
else
  error -> error
end

So - for some subset of errors attempt the retry, while for others give up instantly.

Currently it is impossible:

  • rescue_only works only for exceptions (foo would need to raise instead of returning {:error, reason})
  • atoms is for, well... atoms, not tuples (although with this interesting exception (if the first element of 2–elements tuple is a given atom the retry will kick in)

I can't see clear way of this situation. Some ideas:

  • third option, tuples, which would match any tuples specified by the user (any length, not necessarily (:error, reason}
  • allowing rescue_only to accept all sort of things, mixed - exceptions, atoms, tuples

What are your thoughts on that?

rafal0p avatar Nov 20 '22 20:11 rafal0p

What if it accepted a list of patterns? I would love this for Exceptions as well. I'm willing to try a PR in that direction if interested.

nathanalderson avatar Nov 21 '22 15:11 nathanalderson

Could you give an example of such API?

rafal0p avatar Nov 22 '22 08:11 rafal0p