This is a custom Credo check that looks for a very specific edge case:
- Ecto.Repo.transaction/2 will return a 4 tuple when an error occurs inside a Multi.
- An Oban worker that returns an error 4 tuple will be considered a success.
Many thanks to @andersonmcook for being the human version of this check!
Below is the warning that Oban gives when this happens in iex
iex(14)> [warning] Expected Elixir.MyApp.MultiFailure.perform/1 to return:
- `:ok`
- `:discard`
- `{:ok, value}`
- `{:error, reason}`,
- `{:cancel, reason}`
- `{:discard, reason}`
- `{:snooze, seconds}`
Instead received:
{:error, :alas, :poor_yorick, %{}}
The job will be considered a success.
Here is an example of a potential situation:
def perform(%{}) do
Multi.new()
|> Multi.error(:alas, :poor_yorick)
|> Repo.transaction()
end
Here is a possible resolution (mapping the 4 tuple to a 2 tuple):
def perform(%{}) do
Multi.new()
|> Multi.error(:alas, :poor_yorick)
|> Repo.transaction()
|> case do
{:error, :alas, _, _} -> {:error, "we knew him well"}
any -> any
end
end
Please note that this custom credo check is known to have false positives. In order to address that it would have to grow closer to an interpreter. It has been lightly tested against public repositories, and has moderate unit test coverage.
My Org mode brain dump is progress.org.
If available in Hex, the package can be installed
by adding credo_check_error_handling_ecto_oban
to your list of dependencies in mix.exs
:
def deps do
[
{:credo_check_error_handling_ecto_oban, "~> 0.9.0", only: [:dev, :test], runtime: false}
]
end
Recent versions of credo
:
checks: %{
enabled: [
# ...
{CredoCheckErrorHandlingEctoOban.Check.TransactionErrorInObanJob, []}
]
}
Older versions of credo
:
checks: [
# ...
{CredoCheckErrorHandlingEctoOban.Check.TransactionErrorInObanJob, []}
]
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/credo_check_error_handling_ecto_oban.