Skip to content

Commit

Permalink
feat: bug in one reporter doesn't affect other reporters
Browse files Browse the repository at this point in the history
  • Loading branch information
grzuy committed Aug 28, 2024
1 parent 3ce186b commit 44a8721
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
26 changes: 24 additions & 2 deletions lib/tower.ex
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ defmodule Tower do
passed along to the reporter.
"""

defmodule ReportEventError do
defexception [:original_exception, :reporter]

def message(%__MODULE__{reporter: reporter}) do
"An error occurred while trying to report an event with reporter #{reporter}"
end
end

alias Tower.Event

@default_reporters [Tower.EphemeralReporter]
Expand Down Expand Up @@ -396,9 +404,23 @@ defmodule Tower do
defp report_event(%Event{} = event) do
reporters()
|> Enum.each(fn reporter ->
async(fn ->
report_event(reporter, event)
end)
end

defp report_event(reporter, %Event{reason: %ReportEventError{reporter: reporter}}) do
# Ignore so we don't enter in a loop trying to report to the same buggy reporter
:ignore
end

defp report_event(reporter, event) do
async(fn ->
try do
reporter.report_event(event)
end)
rescue
exception ->
raise ReportEventError, reporter: reporter, original_exception: exception
end
end)
end

Expand Down
51 changes: 51 additions & 0 deletions test/tower_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,57 @@ defmodule TowerTest do
assert is_list(stacktrace)
end

test "bug in one reporter doesn't affect other reporters" do
defmodule BuggyReporter do
@behaviour Tower.Reporter

@impl true
def report_event(_event) do
raise "I have a bug"
end
end

put_env(:reporters, [BuggyReporter, Tower.EphemeralReporter])

capture_log(fn ->
in_unlinked_process(fn ->
1 / 0

Check warning on line 487 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.12)

the call to //2 will fail with ArithmeticError

Check warning on line 487 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 24.3.4.17)

the call to //2 will fail with ArithmeticError

Check warning on line 487 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.12)

the call to //2 will fail with ArithmeticError

Check warning on line 487 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 24.3.4.17)

the call to //2 will fail with ArithmeticError

Check warning on line 487 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.12)

the call to //2 will fail with ArithmeticError

Check warning on line 487 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 24.3.4.17)

the call to //2 will fail with ArithmeticError
end)
end)

assert_eventually(
[
%{
id: id1,
datetime: datetime1,
level: :error,
kind: :error,
reason: %Tower.ReportEventError{
reporter: BuggyReporter,
original_exception: %RuntimeError{message: "I have a bug"}
},
stacktrace: stacktrace1
},
%{
id: id2,
datetime: datetime2,
level: :error,
kind: :error,
reason: %ArithmeticError{message: "bad argument in arithmetic expression"},
stacktrace: stacktrace2
}
] = reported_events()
)

assert String.length(id1) == 36
assert recent_datetime?(datetime1)
assert is_list(stacktrace1)
assert String.length(id2) == 36
assert recent_datetime?(datetime2)
assert is_list(stacktrace2)
assert datetime1 > datetime2
end

defp in_unlinked_process(fun) when is_function(fun, 0) do
{:ok, pid} = Task.Supervisor.start_link()

Expand Down

0 comments on commit 44a8721

Please sign in to comment.