ForgeCredoChecks.NoUnnecessaryCatchAllRaise (forge_credo_checks v0.7.0)

Copy Markdown View Source

Basics

This check is disabled by default.

Learn how to enable it via .credo.exs.

This check has a base priority of high and works with any version of Elixir.

Explanation

Catch-all clauses that only raise discard Elixir's built-in diagnostics.

Why

Elixir's FunctionClauseError already names the function AND shows the actual arguments that failed to match. That is the best diagnostic you can give to a debugger. A hand-written catch-all that raises a generic error throws that signal away:

# Bad -- the error message has a hardcoded string, no failing args
def parse(_), do: raise(ArgumentError, "expected a list")

# Good -- remove the catch-all. The FunctionClauseError will say:
#   "no function clause matching in parse/1
#    with args: (42)"

LLMs generate these defensively because their training data is full of Python/Java patterns where unhandled cases must raise explicitly. In Elixir, let the non-match crash naturally.

Flagged

A def/defp clause where:

  1. Every argument is a wildcard (_ or a _name), AND
  2. The body is exactly one raise(...) call, AND
  3. At least one other clause exists for the same {name, arity} within the same module.

Guarded clauses are not flagged -- the guard implies intentional logic.

Not flagged

  • Catch-alls that return a value ({:error, :invalid})
  • Clauses that log or clean up before raising
  • Zero-arity functions
  • Single-clause functions that raise (stubs, arity redirects, deliberately-raising test doubles). These are not "catch-alls" because there is no other clause to fall through from.

How to fix

Consider whether the raise message adds information beyond what FunctionClauseError already provides:

  • If not, remove the clause entirely.
  • If the message documents valid inputs or redirects to another arity, consider narrowing the guard instead of using all-wildcards, or keep the clause and disable this check inline.

To exclude test files, add to .credo.exs:

{ForgeCredoChecks.NoUnnecessaryCatchAllRaise,
 files: %{excluded: [~r"_test\.exs$", ~r"test/support/"]}}

Check-Specific Parameters

There are no specific parameters for this check.

General Parameters

Like with all checks, general params can be applied.

Parameters can be configured via the .credo.exs config file.