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:
- Belongs to the configured application (
:appconfig) - 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.
Summary
Functions
Derives a component name from a stacktrace.
Returns the list of module patterns to skip when deriving components.
Functions
@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"
Returns the list of module patterns to skip when deriving components.
This combines the app's :ecto_repos modules with any user-configured
patterns.