diff --git a/README.md b/README.md index e022a64..2f4d94c 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ result = retry with: constant_backoff(100) |> Stream.take(10) do after result -> result else - e when is_exception(e) -> raise e + {e, stacktrace} when is_exception(e) -> reraise e, stacktrace e -> e end ``` diff --git a/lib/retry.ex b/lib/retry.ex index c6a1253..c4becc2 100644 --- a/lib/retry.ex +++ b/lib/retry.ex @@ -47,7 +47,7 @@ defmodule Retry do default: [ else: quote do - e when is_exception(e) -> raise e + {e, stacktrace} when is_exception(e) -> reraise e, stacktrace e -> e end, after: @@ -162,8 +162,8 @@ defmodule Retry do fun.() end) |> case do - {:exception, e} -> - case e do + {:exception, e, stacktrace} -> + case {e, stacktrace} do unquote(else_clause) end @@ -336,7 +336,7 @@ defmodule Retry do rescue e -> if e.__struct__ in unquote(exceptions) do - {:cont, {:exception, e}} + {:cont, {:exception, e, __STACKTRACE__}} else reraise e, __STACKTRACE__ end diff --git a/test/retry_test.exs b/test/retry_test.exs index ce23c16..482d57f 100644 --- a/test/retry_test.exs +++ b/test/retry_test.exs @@ -9,6 +9,23 @@ defmodule RetryTest do defmodule(CustomError, do: defexception(message: "custom error!")) describe "retry" do + defp boom, do: raise "boom" + + test "keeps correct stack trace" do + e = + try do + retry with: [1] do + boom() + end + rescue + e -> + Exception.format(:error, e, __STACKTRACE__) + end + + assert e =~ "(RuntimeError) boom" + assert e =~ "test/retry_test.exs:12: RetryTest.boom" + end + test "retries execution for specified attempts when result is error tuple" do {elapsed, _} = :timer.tc(fn -> @@ -94,7 +111,7 @@ defmodule RetryTest do after _ -> :ok else - error -> raise error + {error, _} -> raise error end end end) @@ -113,7 +130,7 @@ defmodule RetryTest do after _ -> :ok else - error -> raise error + {error, _} -> raise error end end end)