Skip to content

Commit c026b58

Browse files
authored
Merge pull request #40 from nirev/master
Only handle 5xx exceptions
2 parents 6d99d4a + c04b0c6 commit c026b58

File tree

2 files changed

+97
-63
lines changed

2 files changed

+97
-63
lines changed

lib/plugsnag.ex

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,37 @@ defmodule Plugsnag do
22
defmacro __using__(options \\ []) do
33
quote location: :keep do
44
use Plug.ErrorHandler
5-
import Plugsnag
65

7-
if :code.is_loaded(Phoenix) do
8-
defp handle_errors(_conn, %{reason: %Phoenix.Router.NoRouteError{}}) do
9-
nil
6+
defp handle_errors(conn, %{reason: exception, kind: :error} = assigns) do
7+
# Only handle exceptions that get rendered as an HTTP 5xx status
8+
if Plug.Exception.status(exception) >= 500 do
9+
do_handle_errors(conn, assigns)
1010
end
1111
end
1212

13-
if :code.is_loaded(Ecto) do
14-
defp handle_errors(conn, %{reason: %Ecto.NoResultsError{}}) do
15-
nil
16-
end
13+
defp handle_errors(conn, %{reason: _exception} = assigns) do
14+
do_handle_errors(conn, assigns)
1715
end
1816

19-
defp handle_errors(conn, %{reason: exception}) do
20-
error_report_builder = unquote(
21-
Keyword.get(
22-
options,
23-
:error_report_builder,
24-
Plugsnag.BasicErrorReportBuilder
17+
defp do_handle_errors(conn, %{reason: exception}) do
18+
error_report_builder =
19+
unquote(
20+
Keyword.get(
21+
options,
22+
:error_report_builder,
23+
Plugsnag.BasicErrorReportBuilder
24+
)
2525
)
26-
)
2726

2827
options =
2928
%Plugsnag.ErrorReport{}
3029
|> error_report_builder.build_error_report(conn)
31-
|> Map.from_struct
32-
|> Keyword.new
30+
|> Map.from_struct()
31+
|> Keyword.new()
3332

34-
apply(reporter(), :report, [exception | [options]])
33+
reporter = Application.get_env(:plugsnag, :reporter, Bugsnag)
34+
apply(reporter, :report, [exception | [options]])
3535
end
3636
end
3737
end
38-
39-
def reporter do
40-
Application.get_env(:plugsnag, :reporter, Bugsnag)
41-
end
4238
end

test/plugsnag_test.exs

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,36 @@ defmodule PlugsnagTest do
33
use Plug.Test
44

55
defmodule TestException do
6-
defexception plug_status: 403, message: "oops"
6+
defexception plug_status: 503, message: "oops"
7+
end
8+
9+
defmodule NotFoundException do
10+
defexception plug_status: 404, message: "not found"
711
end
812

913
defmodule ErrorRaisingPlug do
1014
defmacro __using__(_env) do
1115
quote do
1216
def call(conn, _opts) do
13-
raise Plug.Conn.WrapperError, conn: conn,
14-
kind: :error, stack: System.stacktrace,
15-
reason: TestException.exception([])
17+
raise Plug.Conn.WrapperError,
18+
conn: conn,
19+
kind: :error,
20+
stack: System.stacktrace(),
21+
reason: TestException.exception([])
22+
end
23+
end
24+
end
25+
end
26+
27+
defmodule NotFoundRaisingPlug do
28+
defmacro __using__(_env) do
29+
quote do
30+
def call(conn, _opts) do
31+
raise Plug.Conn.WrapperError,
32+
conn: conn,
33+
kind: :error,
34+
stack: System.stacktrace(),
35+
reason: NotFoundException.exception([])
1636
end
1737
end
1838
end
@@ -23,66 +43,84 @@ defmodule PlugsnagTest do
2343
use ErrorRaisingPlug
2444
end
2545

46+
defmodule NotFoundPlug do
47+
use Plugsnag
48+
use NotFoundRaisingPlug
49+
end
50+
2651
defmodule FakePlugsnag do
2752
def report(exception, options \\ []) do
28-
send self(), {:report, {exception, options}}
53+
send(self(), {:report, {exception, options}})
2954
end
3055
end
3156

3257
setup do
3358
Application.put_env(:plugsnag, :reporter, FakePlugsnag)
3459
end
3560

36-
test "Raising an error on failure" do
37-
conn = conn(:get, "/")
61+
describe "5xx exception" do
62+
test "Raising an error on failure" do
63+
conn = conn(:get, "/")
3864

39-
assert_raise Plug.Conn.WrapperError, "** (PlugsnagTest.TestException) oops", fn ->
40-
TestPlug.call(conn, [])
41-
end
65+
assert_raise Plug.Conn.WrapperError, "** (PlugsnagTest.TestException) oops", fn ->
66+
TestPlug.call(conn, [])
67+
end
4268

43-
assert_received {:report, {%TestException{}, _}}
44-
end
69+
assert_received {:report, {%TestException{}, _}}
70+
end
4571

46-
test "includes connection metadata in the report" do
47-
conn = conn(:get, "/?hello=computer")
72+
test "includes connection metadata in the report" do
73+
conn = conn(:get, "/?hello=computer")
4874

49-
catch_error TestPlug.call(conn, [])
50-
assert_received {:report, {%TestException{}, options}}
51-
metadata = Keyword.get(options, :metadata)
75+
catch_error(TestPlug.call(conn, []))
76+
assert_received {:report, {%TestException{}, options}}
77+
metadata = Keyword.get(options, :metadata)
5278

53-
assert get_in(metadata, [:request,:query_string]) == "hello=computer"
54-
end
79+
assert get_in(metadata, [:request, :query_string]) == "hello=computer"
80+
end
5581

56-
test "allows modifying bugsnag report options before it's sent" do
57-
defmodule TestErrorReportBuilder do
58-
@behaviour Plugsnag.ErrorReportBuilder
82+
test "allows modifying bugsnag report options before it's sent" do
83+
defmodule TestErrorReportBuilder do
84+
@behaviour Plugsnag.ErrorReportBuilder
5985

60-
def build_error_report(error_report, conn) do
61-
user_info = %{
62-
id: conn |> get_req_header("x-user-id") |> List.first
63-
}
86+
def build_error_report(error_report, conn) do
87+
user_info = %{
88+
id: conn |> get_req_header("x-user-id") |> List.first()
89+
}
6490

65-
%{error_report | user: user_info}
91+
%{error_report | user: user_info}
92+
end
6693
end
67-
end
6894

69-
defmodule TestPlugsnagCallbackPlug do
70-
use Plugsnag, error_report_builder: TestErrorReportBuilder
71-
use ErrorRaisingPlug
72-
end
95+
defmodule TestPlugsnagCallbackPlug do
96+
use Plugsnag, error_report_builder: TestErrorReportBuilder
97+
use ErrorRaisingPlug
98+
end
7399

74-
conn = conn(:get, "/")
100+
conn = conn(:get, "/")
75101

76-
conn =
77-
conn
78-
|> put_req_header("x-user-id", "abc123")
102+
conn =
103+
conn
104+
|> put_req_header("x-user-id", "abc123")
79105

80-
catch_error TestPlugsnagCallbackPlug.call(conn, [])
81-
assert_received {:report, {%TestException{}, options}}
106+
catch_error(TestPlugsnagCallbackPlug.call(conn, []))
107+
assert_received {:report, {%TestException{}, options}}
82108

83-
assert Keyword.get(options, :user) == %{
84-
id: "abc123"
85-
}
109+
assert Keyword.get(options, :user) == %{
110+
id: "abc123"
111+
}
112+
end
86113
end
87114

115+
describe "4xx exception" do
116+
test "Raising an error on failure" do
117+
conn = conn(:get, "/")
118+
119+
assert_raise Plug.Conn.WrapperError, "** (PlugsnagTest.NotFoundException) not found", fn ->
120+
NotFoundPlug.call(conn, [])
121+
end
122+
123+
refute_receive {:report, {%NotFoundException{}, _}}, 100
124+
end
125+
end
88126
end

0 commit comments

Comments
 (0)