Packages

Push ErrorTracker errors to your phone with Boop. Attaches to an existing ErrorTracker installation via telemetry.

Current section

Files

Jump to
Raw

README.md

<h1 align="center">BoopErrorTracker</h1>
<p align="center">
<a href="https://hex.pm/packages/boop_error_tracker"><img src="https://img.shields.io/hexpm/v/boop_error_tracker.svg" alt="Hex.pm"></a>
<a href="https://hexdocs.pm/boop_error_tracker"><img src="https://img.shields.io/badge/hex-docs-blue.svg" alt="Hex Docs"></a>
<a href="https://hex.pm/packages/boop_error_tracker"><img src="https://img.shields.io/hexpm/dt/boop_error_tracker.svg" alt="Downloads"></a>
<a href="https://github.com/chrisgreg/boop_error_tracker/blob/main/LICENSE"><img src="https://img.shields.io/hexpm/l/boop_error_tracker.svg" alt="License"></a>
</p>
<p align="center"><strong>Your Elixir app raised. Your phone knows.</strong></p>
Sends [ErrorTracker](https://github.com/elixir-error-tracker/error-tracker) errors to
your iPhone through [Boop](https://github.com/chrisgreg/boop), the tiny self-hosted
push notification inbox.
ErrorTracker deliberately does not do notifications. This package attaches to the
telemetry events it already emits, so you install it next to ErrorTracker and
nothing about ErrorTracker changes.
## Installation
```elixir
def deps do
[
{:error_tracker, "~> 0.9"},
{:boop_ex, "~> 1.1"},
{:boop_error_tracker, "~> 1.1"}
]
end
```
Set up ErrorTracker as usual (repo, migration, router). Then configure the Boop client and this package:
```elixir
# config/runtime.exs
config :boop_ex,
url: System.fetch_env!("BOOP_URL"),
api_key: System.fetch_env!("BOOP_API_KEY")
config :boop_error_tracker,
environment: config_env(), # tagged on every event
source: "my_app", # shown next to the error in Boop; default "error_tracker"
error_tracker_url: "https://my-app.com/dev/errors", # "Open in ErrorTracker" button on every push
enabled: config_env() == :prod
```
That's it. The handler attaches when the application starts.
## What you get
Each push opens a full error page in the Boop app: exception type and message, the stacktrace with your app's frames highlighted, ErrorTracker's context and breadcrumbs, and tags for environment, source function/line and the ErrorTracker ids so you can jump to the ErrorTracker UI.
| Event | Default | Meaning |
| --- | --- | --- |
| `:new` | on | An error ErrorTracker has never seen before |
| `:unresolved` | on | An error you marked resolved in the ErrorTracker UI happened again |
| `:occurrence` | off | Every occurrence of any error, throttled per error (`throttle`, default 10 minutes) |
Errors muted in ErrorTracker are never sent.
### Grouped in the inbox
Each event carries ErrorTracker's fingerprint, and Boop (1.2.0+) shows one inbox row per fingerprint — `KeyError ×47 · First seen 09:31 · Last seen 10:42` — that opens the individual occurrences. That makes `:occurrence` notifications practical: the pushes still arrive, but the inbox stays one row per error.
### Buttons on the push
Set `error_tracker_url` to the base URL of your ErrorTracker dashboard's error pages (the path you gave `error_tracker_dashboard` in your router plus `/errors`) and every push carries an **Open in ErrorTracker** button, on the notification itself and in the event detail. Add your own with `actions`:
```elixir
config :boop_error_tracker,
error_tracker_url: "https://my-app.com/dev/errors",
actions: fn error, occurrence ->
[%{label: "Runbook", url: "https://wiki.example.com/errors/#{error.kind}"}]
end
```
`actions` may be a static list or a function of the error (and optionally the occurrence). Boop shows at most three buttons; if the function raises, the event is still sent without the extra buttons.
## Options
```elixir
config :boop_error_tracker,
enabled: true,
environment: "prod",
source: "my_app",
level: :error, # :critical makes pushes prominent
notify_on: [:new, :unresolved], # add :occurrence for ongoing errors
throttle: :timer.minutes(10), # minimum gap between :occurrence pushes for the same error
in_app: [:my_app, :my_app_web], # which OTP apps count as "your code" in stacktraces
tags: %{team: "web"}, # static tags on every event
error_tracker_url: "https://my-app.com/dev/errors", # "Open in ErrorTracker" button; nil = none
actions: [] # extra buttons: a list or fn error, occurrence -> [...] end
```
Sending goes through `Boop.send_async/2`: it never blocks the process that raised, never raises, and logs failures at `:warning`.
## Usage rules for AI agents
Ships a [`usage-rules.md`](usage-rules.md) for [usage_rules](https://hexdocs.pm/usage_rules): `mix usage_rules.sync AGENTS.md --all --link-to-folder deps`.
## Licence
MIT.