Basics
This check is disabled by default.
Learn how to enable it via .credo.exs.
This check has a base priority of normal and works with any version of Elixir.
Explanation
Avoid wide else blocks on with expressions.
Why
All failure clauses from every <- step are flattened into a single
else block. The block stops describing which step failed and
becomes a dispatch table on error shapes - and an exhaustive one,
since any unmatched failure raises WithClauseError.
Prefer letting non-matches fall through: if every <- step returns a
uniform shape (:ok | {:error, reason} or {:ok, value} | {:error, reason}),
the bare with (no else) returns the first error verbatim and the
caller decides what to do.
How to fix
For each <- step that returns a step-specific shape, wrap the call
in a private helper that returns the uniform shape. Then delete the
else block.
# BEFORE - else dispatches on step-specific shapes
with {:ok, user} <- Repo.get(User, id) |> ok_or_nil(),
true <- User.active?(user) do
{:ok, user}
else
nil -> {:error, :not_found}
false -> {:error, :inactive}
{:error, _} = err -> err
end
# AFTER - each step returns {:ok, _} | {:error, _}; no else needed
with {:ok, user} <- find_user(id),
:ok <- ensure_active(user) do
{:ok, user}
end
defp find_user(id) do
case Repo.get(User, id) do
nil -> {:error, :not_found}
user -> {:ok, user}
end
end
defp ensure_active(user) do
if User.active?(user), do: :ok, else: {:error, :inactive}
endWhat NOT to do
Do not collapse the else into a single catch-all clause to silence
this check - that loses the per-step error context entirely:
# STILL BAD
else
err -> {:error, err}
endPush the normalization upstream into helpers, as shown above.
Configuration
This check fires when a with has more than :max_clauses else
clauses (default 1). Set :max_clauses to 0 to forbid else
entirely; raise it for codebases that accept wider blocks.
Check-Specific Parameters
Use the following parameters to configure this check:
:max_clauses
Maximum number of else clauses allowed before the check fires. Default: 1.
This parameter defaults to 1.
General Parameters
Like with all checks, general params can be applied.
Parameters can be configured via the .credo.exs config file.