Honeybadger.ComponentDeriver (Honeybadger v0.30.0)

Copy Markdown View Source

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.

Summary

Functions

Derives a component name from a stacktrace.

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

Functions

derive(stacktrace, opts \\ [])

@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(app \\ Honeybadger.get_env(:app))

@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.