diff --git a/lib/error_tracker/error_notifier.ex b/lib/error_tracker/error_notifier.ex index c1616146..8c64a920 100644 --- a/lib/error_tracker/error_notifier.ex +++ b/lib/error_tracker/error_notifier.ex @@ -28,12 +28,18 @@ defmodule ErrorTracker.ErrorNotifier do case event_name do [:error_tracker, :error, :new] -> reason = truncate_reason(metadata.occurrence.reason) - {_result, new_state} = maybe_notify(metadata.occurrence, "New Error! (#{reason})", state) + + {_result, new_state} = + maybe_notify(metadata.occurrence, metadata.error.muted, "New Error! (#{reason})", state) + {:noreply, new_state} [:error_tracker, :occurrence, :new] -> reason = truncate_reason(metadata.occurrence.reason) - {_result, new_state} = maybe_notify(metadata.occurrence, "Error: #{reason}", state) + + {_result, new_state} = + maybe_notify(metadata.occurrence, metadata.error.muted, "Error: #{reason}", state) + {:noreply, new_state} _ -> @@ -74,7 +80,12 @@ defmodule ErrorTracker.ErrorNotifier do ) end - defp maybe_notify(occurrence, header, state) do + defp maybe_notify(occurrence, true, _header, state) do + Logger.debug("Skipping notification for muted error #{occurrence.error_id}") + {:skipped, state} + end + + defp maybe_notify(occurrence, _muted, header, state) do error_id = occurrence.error_id now = System.system_time(:second) throttle_seconds = config()[:throttle_seconds] || 10 diff --git a/test/error_tracker/error_notifier_test.exs b/test/error_tracker/error_notifier_test.exs index 75a172d7..0f6ebc2b 100644 --- a/test/error_tracker/error_notifier_test.exs +++ b/test/error_tracker/error_notifier_test.exs @@ -3,7 +3,7 @@ defmodule ErrorTracker.ErrorNotifierTest do import Swoosh.TestAssertions - alias ErrorTracker.ErrorNotifier + alias ErrorTracker.{Error, ErrorNotifier, Occurrence} @config [ from_email: "test@example.com", @@ -13,8 +13,8 @@ defmodule ErrorTracker.ErrorNotifierTest do ] defp occurrence(attrs \\ %{}) do - Map.merge( - %{ + struct!( + %Occurrence{ error_id: 42, reason: "** (RuntimeError) something went wrong", context: %{"request.path" => "/test", "live_view.view" => "TestLive"}, @@ -115,7 +115,7 @@ defmodule ErrorTracker.ErrorNotifierTest do {:ok, pid} = ErrorNotifier.start_link([]) :telemetry.execute([:error_tracker, :error, :new], %{}, %{ - error: %{id: 1}, + error: %ErrorTracker.Error{id: 1}, occurrence: occurrence(%{error_id: 1}) }) @@ -124,6 +124,7 @@ defmodule ErrorTracker.ErrorNotifierTest do # Second notification for same error: throttled :telemetry.execute([:error_tracker, :occurrence, :new], %{}, %{ + error: %ErrorTracker.Error{id: 1}, occurrence: occurrence(%{error_id: 1}) }) @@ -134,6 +135,22 @@ defmodule ErrorTracker.ErrorNotifierTest do end end + describe "skipping" do + test "skips notification when error is muted" do + Application.put_env(:music_library, ErrorNotifier, @config) + {:ok, pid} = ErrorNotifier.start_link([]) + + :telemetry.execute([:error_tracker, :error, :new], %{}, %{ + error: %Error{id: 1, muted: true}, + occurrence: occurrence(%{error_id: 1}) + }) + + refute_email_sent() + + GenServer.stop(pid) + end + end + describe "telemetry integration" do test "sends email on :error_tracker :error :new event" do Application.put_env(:music_library, ErrorNotifier, @config) @@ -141,7 +158,7 @@ defmodule ErrorTracker.ErrorNotifierTest do {:ok, pid} = ErrorNotifier.start_link([]) :telemetry.execute([:error_tracker, :error, :new], %{}, %{ - error: %{id: 99}, + error: %Error{id: 99}, occurrence: occurrence(%{error_id: 99}) })