From b1a171132914075e5aeb1d99027cc8b7d144c9a7 Mon Sep 17 00:00:00 2001 From: Gonzalo <456459+grzuy@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:23:04 -0300 Subject: [PATCH] feat: reports Tower.Event.metadata as ErrorTracker occurrence context --- lib/tower_error_tracker/reporter.ex | 45 ++++++++++++++--------------- test/tower_error_tracker_test.exs | 22 ++++++++++++++ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/lib/tower_error_tracker/reporter.ex b/lib/tower_error_tracker/reporter.ex index cfed6ef..68dc121 100644 --- a/lib/tower_error_tracker/reporter.ex +++ b/lib/tower_error_tracker/reporter.ex @@ -1,35 +1,20 @@ defmodule TowerErrorTracker.Reporter do @moduledoc false - def report_event(%Tower.Event{ - kind: :error, - reason: exception, - stacktrace: stacktrace, - plug_conn: plug_conn - }) do - ErrorTracker.report(exception, stacktrace, context(plug_conn)) + def report_event(%Tower.Event{kind: :error, reason: exception, stacktrace: stacktrace} = event) do + ErrorTracker.report(exception, stacktrace, context(event)) :ok end - def report_event(%Tower.Event{ - kind: :throw, - reason: value, - stacktrace: stacktrace, - plug_conn: plug_conn - }) do - ErrorTracker.report({:throw, inspect(value)}, stacktrace, context(plug_conn)) + def report_event(%Tower.Event{kind: :throw, reason: value, stacktrace: stacktrace} = event) do + ErrorTracker.report({:throw, inspect(value)}, stacktrace, context(event)) :ok end - def report_event(%Tower.Event{ - kind: :exit, - reason: reason, - stacktrace: stacktrace, - plug_conn: plug_conn - }) do - ErrorTracker.report({:exit, Exception.format_exit(reason)}, stacktrace, context(plug_conn)) + def report_event(%Tower.Event{kind: :exit, reason: reason, stacktrace: stacktrace} = event) do + ErrorTracker.report({:exit, Exception.format_exit(reason)}, stacktrace, context(event)) :ok end @@ -38,12 +23,24 @@ defmodule TowerErrorTracker.Reporter do :ignore end + defp context(%{metadata: metadata, plug_conn: plug_conn}) do + %{} + |> Map.merge(metadata_context(metadata)) + |> Map.merge(request_context(plug_conn)) + end + + defp metadata_context(metadata) when is_map(metadata) and map_size(metadata) > 0 do + %{metadata: metadata} + end + + defp metadata_context(_), do: %{} + if Code.ensure_loaded?(Plug.Conn) do - defp context(%Plug.Conn{} = conn) do + defp request_context(%Plug.Conn{} = conn) do %{request: request_data(conn)} end - defp context(_), do: %{} + defp request_context(_), do: %{} defp request_data(%Plug.Conn{} = conn) do %{ @@ -52,6 +49,6 @@ defmodule TowerErrorTracker.Reporter do } end else - defp context(_), do: %{} + defp request_context(_), do: %{} end end diff --git a/test/tower_error_tracker_test.exs b/test/tower_error_tracker_test.exs index 4f60723..baec9be 100644 --- a/test/tower_error_tracker_test.exs +++ b/test/tower_error_tracker_test.exs @@ -199,6 +199,28 @@ defmodule TowerErrorTrackerTest do ) end + test "reports event metadata as context" do + Tower.report_exception(RuntimeError.exception("Oops!"), [], metadata: %{user_id: 123}) + + assert_eventually( + [ + %{ + kind: "Elixir.RuntimeError", + reason: "Oops!", + occurrences: [ + %{ + context: %{ + "metadata" => %{ + "user_id" => 123 + } + } + } + ] + } + ] = TestApp.Repo.all(ErrorTracker.Error) |> TestApp.Repo.preload(:occurrences) + ) + end + defp in_unlinked_process(fun) when is_function(fun, 0) do {:ok, pid} = Task.Supervisor.start_link()