Skip to content

Commit

Permalink
Handle exits in the same way we do throws and exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrudel committed Dec 7, 2024
1 parent 9d86e27 commit 0a3301a
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/bandit/pipeline.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,14 @@ defmodule Bandit.Pipeline do
{:upgrade, adapter.transport, protocol, opts}
end
rescue
exception -> handle_error(:error, exception, __STACKTRACE__, transport, span, opts, conn)
exception ->
handle_error(:error, exception, __STACKTRACE__, transport, span, opts, conn)
catch
:throw, value ->
handle_error(:throw, value, __STACKTRACE__, transport, span, opts, conn)

:exit, value ->
handle_error(:exit, value, __STACKTRACE__, transport, span, opts, conn)
end
rescue
exception ->
Expand Down Expand Up @@ -197,7 +201,7 @@ defmodule Bandit.Pipeline do
end

@spec handle_error(
:error | :throw,
:error | :throw | :exit,
Exception.t() | term(),
Exception.stacktrace(),
Bandit.HTTPTransport.t(),
Expand Down
35 changes: 35 additions & 0 deletions test/bandit/http1/request_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1958,6 +1958,21 @@ defmodule HTTP1RequestTest do
throw("something")
end

test "returns a 500 if the plug exits", context do
output =
capture_log(fn ->
response = Req.get!(context.req, url: "/exits")
assert response.status == 500
Process.sleep(100)
end)

assert output =~ "(exit) \"something\""
end

def exits(_conn) do
exit("something")
end

test "does not send an error response if the plug has already sent one before raising",
context do
output =
Expand Down Expand Up @@ -2387,6 +2402,26 @@ defmodule HTTP1RequestTest do
def uncaught_throw(_conn) do
throw("thrown")
end

test "it should not send `exception` events for exiting requests", context do
output =
capture_log(fn ->
{:ok, collector_pid} =
start_supervised({Bandit.TelemetryCollector, [[:bandit, :request, :exception]]})

Req.get!(context.req, url: "/uncaught_exit")

Process.sleep(100)

assert [] = Bandit.TelemetryCollector.get_events(collector_pid)
end)

assert output =~ "(exit) \"exited\""
end

def uncaught_exit(_conn) do
exit("exited")
end
end

describe "connection closure / error handling" do
Expand Down
20 changes: 20 additions & 0 deletions test/bandit/http2/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1046,5 +1046,25 @@ defmodule HTTP2PlugTest do
def uncaught_throw(_conn) do
throw("thrown")
end

test "it should not send `exception` events for exiting requests", context do
output =
capture_log(fn ->
{:ok, collector_pid} =
start_supervised({Bandit.TelemetryCollector, [[:bandit, :request, :exception]]})

Req.get!(context.req, url: "/uncaught_exit")

Process.sleep(100)

assert [] = Bandit.TelemetryCollector.get_events(collector_pid)
end)

assert output =~ "(exit) \"exited\""
end

def uncaught_exit(_conn) do
exit("exited")
end
end
end

0 comments on commit 0a3301a

Please sign in to comment.