Skip to content

Commit

Permalink
fix: properly reports common :gen_server abnormal exits
Browse files Browse the repository at this point in the history
  • Loading branch information
grzuy committed Oct 24, 2024
1 parent 13ab412 commit 8777791
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 63 deletions.
2 changes: 1 addition & 1 deletion lib/tower_slack/reporter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ defmodule TowerSlack.Reporter do
reason: reason,
stacktrace: stacktrace
}) do
post_message(id, similarity_id, "Exit", reason, stacktrace)
post_message(id, similarity_id, "Exit", Exception.format_exit(reason), stacktrace)
end

defp do_report_event(%Tower.Event{
Expand Down
196 changes: 134 additions & 62 deletions test/tower_slack_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,73 +14,132 @@ defmodule TowerSlackTest do
end

test "reports arithmetic error", %{bypass: bypass} do
# ref message synchronization trick copied from
# https://github.com/PSPDFKit-labs/bypass/issues/112
parent = self()
ref = make_ref()

Bypass.expect_once(bypass, "POST", "/webhook", fn conn ->
{:ok, body, conn} = Plug.Conn.read_body(conn)

assert(
%{
"blocks" => [
%{
"type" => "rich_text",
"elements" => [
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" =>
"[tower_slack][test] ArithmeticError: bad argument in arithmetic expression"
}
]
},
%{
"type" => "rich_text_preformatted",
"elements" => _,
"border" => 0
},
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "id: " <> _id_rest
}
]
},
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "similarity_id: " <> _similarity_rest
}
]
}
]
}
]
} = Jason.decode!(body)
)

send(parent, {ref, :sent})
waiting_for(fn done ->
Bypass.expect_once(bypass, "POST", "/webhook", fn conn ->
{:ok, body, conn} = Plug.Conn.read_body(conn)

assert(
%{
"blocks" => [
%{
"type" => "rich_text",
"elements" => [
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" =>
"[tower_slack][test] ArithmeticError: bad argument in arithmetic expression"
}
]
},
%{
"type" => "rich_text_preformatted",
"elements" => _,
"border" => 0
},
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "id: " <> _id_rest
}
]
},
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "similarity_id: " <> _similarity_rest
}
]
}
]
}
]
} = Jason.decode!(body)
)

done.()

conn
|> Plug.Conn.put_resp_content_type("application/json")
|> Plug.Conn.resp(200, Jason.encode!(%{"ok" => true}))
end)

conn
|> Plug.Conn.put_resp_content_type("application/json")
|> Plug.Conn.resp(200, Jason.encode!(%{"ok" => true}))
capture_log(fn ->
in_unlinked_process(fn ->
1 / 0

Check warning on line 75 in test/tower_slack_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.13)

the call to //2 will fail with ArithmeticError

Check warning on line 75 in test/tower_slack_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.13)

the call to //2 will fail with ArithmeticError

Check warning on line 75 in test/tower_slack_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.13)

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

capture_log(fn ->
in_unlinked_process(fn ->
1 / 0
test "reports :gen_server bad exit", %{bypass: bypass} do
waiting_for(fn done ->
Bypass.expect_once(bypass, "POST", "/webhook", fn conn ->
{:ok, body, conn} = Plug.Conn.read_body(conn)

assert(
%{
"blocks" => [
%{
"type" => "rich_text",
"elements" => [
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "[tower_slack][test] Exit: bad return value: \"bad value\""
}
]
},
%{
"type" => "rich_text_preformatted",
"elements" => _,
"border" => 0
},
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "id: " <> _id_rest
}
]
},
%{
"type" => "rich_text_section",
"elements" => [
%{
"type" => "text",
"text" => "similarity_id: " <> _similarity_rest
}
]
}
]
}
]
} = Jason.decode!(body)
)

done.()

conn
|> Plug.Conn.put_resp_content_type("application/json")
|> Plug.Conn.resp(200, Jason.encode!(%{"ok" => true}))
end)
end)

assert_receive({^ref, :sent}, 500)
capture_log(fn ->
in_unlinked_process(fn ->
exit({:bad_return_value, "bad value"})
end)
end)
end)
end

test "protects from repeated events", %{bypass: bypass} do
Expand Down Expand Up @@ -115,4 +174,17 @@ defmodule TowerSlackTest do
|> Task.Supervisor.async_nolink(fun)
|> Task.yield()
end

defp waiting_for(fun) do
# ref message synchronization trick copied from
# https://github.com/PSPDFKit-labs/bypass/issues/112
parent = self()
ref = make_ref()

fun.(fn ->
send(parent, {ref, :sent})
end)

assert_receive({^ref, :sent}, 500)
end
end

0 comments on commit 8777791

Please sign in to comment.