Skip to content

Commit

Permalink
HTTP/1 responses respect Plug.Exception implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
mtrudel committed Apr 19, 2024
1 parent 605f443 commit 07d5ebc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
18 changes: 5 additions & 13 deletions lib/bandit/http1/socket.ex
Original file line number Diff line number Diff line change
Expand Up @@ -383,28 +383,20 @@ defmodule Bandit.HTTP1.Socket do
def supported_upgrade?(_socket, protocol), do: protocol == :websocket

def send_on_error(%@for{} = socket, %Bandit.HTTPError{} = error) do
_ = send_error(socket, error.status)
socket = send_error(socket, error.status)
%{socket | write_state: :sent}
end

def send_on_error(%@for{} = socket, _error) do
_ = send_error(socket, 500)
def send_on_error(%@for{} = socket, error) do
socket = send_error(socket, Plug.Exception.status(error))
%{socket | write_state: :sent}
end

defp send_error(socket, status) do
receive do
{:plug_conn, :sent} -> :ok
{:plug_conn, :sent} -> socket
after
0 ->
try do
reason = Plug.Conn.Status.reason_phrase(status)
response_line = "#{socket.version} #{status} #{reason}\r\n\r\n"
_ = ThousandIsland.Socket.send(socket.socket, response_line)
ThousandIsland.Socket.close(socket.socket)
rescue
_ -> :ok
end
0 -> send_headers(socket, status, [], :no_body)
end
end

Expand Down
32 changes: 32 additions & 0 deletions test/bandit/http2/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,38 @@ defmodule HTTP2PlugTest do
end
end

describe "error response & logging" do
test "it should return 500 and log when unknown exceptions are raised", context do
output =
capture_log(fn ->
{:ok, response} = Req.get(context.req, url: "/unknown_crasher")
assert response.status == 500
Process.sleep(100)
end)

assert output =~ "(RuntimeError) boom"
end

def unknown_crasher(_conn) do
raise "boom"
end

test "it should return the code and log when known exceptions are raised", context do
output =
capture_log(fn ->
{:ok, response} = Req.get(context.req, url: "/known_crasher")
assert response.status == 456
Process.sleep(100)
end)

assert output =~ "(SafeError) boom"
end

def known_crasher(_conn) do
raise SafeError, "boom"
end
end

test "reading request headers", context do
response =
Req.head!(context.req, url: "/header_read_test", headers: [{"x-request-header", "Request"}])
Expand Down

0 comments on commit 07d5ebc

Please sign in to comment.