Skip to content

Commit

Permalink
WIP Phoenix.ActionClauseError
Browse files Browse the repository at this point in the history
  • Loading branch information
grzuy committed Nov 7, 2024
1 parent 625ac35 commit 3f65427
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 9 deletions.
18 changes: 14 additions & 4 deletions lib/tower/bandit_exception_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ defmodule Tower.BanditExceptionHandler do
},
stacktrace: stacktrace
}) do
Exception.normalize(:error, reason, stacktrace)
|> Tower.report_exception(stacktrace, plug_conn: conn)
exception = Exception.normalize(:error, reason, stacktrace)

if report?(exception) do
Tower.report_exception(exception, stacktrace, plug_conn: conn)
end
end

defp handle_event_metadata(%{
Expand All @@ -50,8 +53,11 @@ defmodule Tower.BanditExceptionHandler do
conn: conn
})
when is_exception(reason) do
Exception.normalize(:error, reason, stacktrace)
|> Tower.report_exception(stacktrace, plug_conn: conn)
exception = Exception.normalize(:error, reason, stacktrace)

if report?(exception) do
Tower.report_exception(exception, stacktrace, plug_conn: conn)
end
end

defp handle_event_metadata(event_metadata) do
Expand All @@ -61,4 +67,8 @@ defmodule Tower.BanditExceptionHandler do

:ignored
end

defp report?(exception) do
Plug.Exception.status(exception) in 500..599

Check warning on line 72 in lib/tower/bandit_exception_handler.ex

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.15)

Plug.Exception.status/1 is undefined (module Plug.Exception is not available or is yet to be defined)

Check warning on line 72 in lib/tower/bandit_exception_handler.ex

View workflow job for this annotation

GitHub Actions / main (1.15, 24.3.4.17)

Plug.Exception.status/1 is undefined (module Plug.Exception is not available or is yet to be defined)

Check warning on line 72 in lib/tower/bandit_exception_handler.ex

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.15)

Plug.Exception.status/1 is undefined (module Plug.Exception is not available or is yet to be defined)

Check warning on line 72 in lib/tower/bandit_exception_handler.ex

View workflow job for this annotation

GitHub Actions / main (1.15, 24.3.4.17)

Plug.Exception.status/1 is undefined (module Plug.Exception is not available or is yet to be defined)
end
end
4 changes: 3 additions & 1 deletion test/support/phoenix_app/endpoint.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
defmodule Tower.PhoenixApp.Endpoint do
use Phoenix.Endpoint, otp_app: :phoenix_app

plug(Tower.TestPlug)
# So that it fetches query params
plug(Plug.Parsers, parsers: [])
plug(Tower.PhoenixApp.Router)
end
4 changes: 2 additions & 2 deletions test/support/phoenix_app/error_html.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Tower.PhoenixApp.ErrorHTML do
def render("500.html", _assigns) do
"Internal Server Error"
def render(template, _assigns) do
Phoenix.Controller.status_message_from_template(template)
end
end
25 changes: 25 additions & 0 deletions test/support/phoenix_app/home_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule Tower.PhoenixApp.HomeController do
use Phoenix.Controller, formats: [:html], put_default_views: false

def show(conn, %{"param" => "valid"}) do
Plug.Conn.send_resp(conn, 200, "Hey!")
end

def runtime_error(conn, _params) do
raise "an error"

Plug.Conn.send_resp(conn, 200, "OK")
end

def abnormal_exit(conn, _params) do
exit(:abnormal)

Plug.Conn.send_resp(conn, 200, "OK")
end

def uncaught_throw(conn, _params) do
throw("something")

Plug.Conn.send_resp(conn, 200, "OK")
end
end
8 changes: 8 additions & 0 deletions test/support/phoenix_app/router.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule Tower.PhoenixApp.Router do
use Phoenix.Router, helpers: false

get("/runtime-error", Tower.PhoenixApp.HomeController, :runtime_error)
get("/abnormal-exit", Tower.PhoenixApp.HomeController, :abnormal_exit)
get("/uncaught-throw", Tower.PhoenixApp.HomeController, :uncaught_throw)
get("/show", Tower.PhoenixApp.HomeController, :show)
end
35 changes: 33 additions & 2 deletions test/tower/phoenix_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule TowerPhoenixTest do

import ExUnit.CaptureLog, only: [capture_log: 1]

setup do
setup context do
on_exit(fn ->
Tower.EphemeralReporter.reset()
end)
Expand All @@ -17,7 +17,11 @@ defmodule TowerPhoenixTest do
Application.put_env(
:phoenix_app,
Tower.PhoenixApp.Endpoint,
adapter: Bandit.PhoenixAdapter,
adapter:
case context[:adapter] do
:bandit -> Bandit.PhoenixAdapter
:cowboy -> Phoenix.Endpoint.Cowboy2Adapter
end,
server: true,
http: [port: port],
url: [scheme: "http", port: port, host: host],
Expand All @@ -31,6 +35,7 @@ defmodule TowerPhoenixTest do
%{base_url: "http://#{host}:#{port}"}
end

@tag adapter: :bandit
test "reports runtime error during Phoenix.Endpoint dispatch with Bandit", %{base_url: base_url} do
url = base_url <> "/runtime-error"

Expand Down Expand Up @@ -58,6 +63,7 @@ defmodule TowerPhoenixTest do
assert Plug.Conn.request_url(plug_conn) == url
end

@tag adapter: :bandit
test "reports uncaught throw during Phoenix.Endpoint dispatch with Bandit", %{
base_url: base_url
} do
Expand Down Expand Up @@ -89,6 +95,7 @@ defmodule TowerPhoenixTest do
assert [] = stacktrace
end

@tag adapter: :bandit
test "reports abnormal exit during Phoenix.Endpoint dispatch with Bandit", %{base_url: base_url} do
capture_log(fn ->
{:ok, {{_, 500, _}, _, _}} = :httpc.request(base_url <> "/abnormal-exit")
Expand All @@ -114,6 +121,30 @@ defmodule TowerPhoenixTest do
assert [_ | _] = stacktrace
end

@tag adapter: :cowboy
test "doesn't report exceptions that return 4xx status codes with Cowboy", %{base_url: base_url} do
# Forcing Phoenix.ActionClauseError
url = base_url <> "/show?param=invalid"

capture_log(fn ->
{:ok, {{_, 400, _}, _, _}} = :httpc.request(url)
end)

assert [] = Tower.EphemeralReporter.events()
end

@tag adapter: :bandit
test "doesn't report exceptions that return 4xx status codes with Bandit", %{base_url: base_url} do
# Forcing Phoenix.ActionClauseError
url = base_url <> "/show?param=invalid"

capture_log(fn ->
{:ok, {{_, 400, _}, _, _}} = :httpc.request(url)
end)

assert [] = Tower.EphemeralReporter.events()
end

defp recent_datetime?(datetime) do
diff =
:logger.timestamp()
Expand Down

0 comments on commit 3f65427

Please sign in to comment.