# `Honeybadger.ComponentDeriver`
[🔗](https://github.com/honeybadger-io/honeybadger-elixir/blob/v0.30.2/lib/honeybadger/component_deriver.ex#L1)

Derives a component name from a stacktrace for better error grouping.

When errors occur outside of web requests (e.g., in background jobs, GenServers,
or Tasks), there's no Phoenix controller to use as the component. This module
analyzes the stacktrace to find a meaningful "origin" module that can serve as
the component for fingerprinting purposes.

The Honeybadger API uses the component field (along with exception class and
the first application backtrace frame) to group errors. Without a component,
errors with similar stacktraces may be incorrectly grouped together.

## How It Works

The deriver walks through the stacktrace looking for the first frame that:
1. Belongs to the configured application (`:app` config)
2. Is not in the list of skipped modules

The app ownership check already excludes library frames (`Ecto.Repo`,
`Postgrex`, etc.), since those modules belong to their own OTP applications.
The skip list exists for modules that *do* belong to the app but don't
indicate where an error originated — most notably the app's Ecto repo
(e.g. `MyApp.Repo`), which appears in every database error's stacktrace.
Repo modules are skipped automatically by reading the app's `:ecto_repos`
configuration.

## Configuration

You can skip additional modules:

    config :honeybadger,
      component_deriver_skip_patterns: [
        MyApp.CustomInfraModule,
        ~r/^MyApp\.Internal/,
        "MyApp.Utilities"
      ]

Patterns can be module atoms, strings, or regexes.

# `derive`

```elixir
@spec derive(Exception.stacktrace(), keyword()) :: String.t() | nil
```

Derives a component name from a stacktrace.

Returns the module name as a string if a suitable component is found,
or `nil` if no suitable module could be determined.

## Parameters

  * `stacktrace` - An Elixir stacktrace (list of stack frames)
  * `opts` - Optional keyword list with:
    * `:app` - The application atom to match against (defaults to Honeybadger config)
    * `:skip_patterns` - List of regex patterns for modules to skip

## Examples

    iex> stacktrace = [
    ...>   {MyApp.Users, :create, 2, [file: 'lib/my_app/users.ex', line: 42]},
    ...>   {Ecto.Repo, :insert, 2, [file: 'lib/ecto/repo.ex', line: 100]}
    ...> ]
    iex> Honeybadger.ComponentDeriver.derive(stacktrace)
    "MyApp.Users"

# `skip_patterns`

```elixir
@spec skip_patterns(atom() | nil) :: [Regex.t()]
```

Returns the list of module patterns to skip when deriving components.

This combines the app's `:ecto_repos` modules with any user-configured
patterns.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
