Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include more information on AlreadySentError errors #6000

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions lib/phoenix/controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,16 @@ defmodule Phoenix.Controller do
put_private_view(conn, :phoenix_view, :replace, formats)
end

def put_view(%Plug.Conn{}, _module), do: raise(AlreadySentError)
def put_view(%Plug.Conn{} = conn, module) do
raise(AlreadySentError, """
the response was already sent.

Status code: #{conn.status}
Request path: #{conn.request_path}
Method: #{conn.method}
View module: #{inspect(module)}
""")
end

defp put_private_view(conn, priv_key, kind, formats) when is_list(formats) do
formats = Enum.into(formats, %{}, fn {format, value} -> {to_string(format), value} end)
Expand Down Expand Up @@ -578,7 +587,16 @@ defmodule Phoenix.Controller do
put_private_view(conn, :phoenix_view, :new, formats)
end

def put_new_view(%Plug.Conn{}, _module), do: raise(AlreadySentError)
def put_new_view(%Plug.Conn{} = conn, module) do
raise(AlreadySentError, """
the response was already sent.

Status code: #{conn.status}
Request path: #{conn.request_path}
Method: #{conn.method}
View module: #{inspect(module)}
""")
end

@doc """
Retrieves the current view for the given format.
Expand Down Expand Up @@ -642,7 +660,14 @@ defmodule Phoenix.Controller do
if state in @unsent do
put_private_layout(conn, :phoenix_layout, :replace, layout)
else
raise AlreadySentError
raise AlreadySentError, """
the response was already sent.

Status code: #{conn.status}
Request path: #{conn.request_path}
Method: #{conn.method}
Layout: #{inspect(layout)}
"""
end
end

Expand Down Expand Up @@ -718,7 +743,16 @@ defmodule Phoenix.Controller do
@spec put_new_layout(Plug.Conn.t(), [{format :: atom, layout}] | layout) :: Plug.Conn.t()
def put_new_layout(%Plug.Conn{state: state} = conn, layout)
when (is_tuple(layout) and tuple_size(layout) == 2) or is_list(layout) or layout == false do
unless state in @unsent, do: raise(AlreadySentError)
unless state in @unsent do
raise(AlreadySentError, """
the response was already sent.

Status code: #{conn.status}
Request path: #{conn.request_path}
Method: #{conn.method}
Layout: #{inspect(layout)}
""")
end
put_private_layout(conn, :phoenix_layout, :new, layout)
end

Expand Down Expand Up @@ -759,7 +793,14 @@ defmodule Phoenix.Controller do
if state in @unsent do
put_private_layout(conn, :phoenix_root_layout, :replace, layout)
else
raise AlreadySentError
raise AlreadySentError, """
the response was already sent.

Status code: #{conn.status}
Request path: #{conn.request_path}
Method: #{conn.method}
Layout: #{inspect(layout)}
"""
end
end

Expand All @@ -784,7 +825,15 @@ defmodule Phoenix.Controller do
put_private(conn, :phoenix_layout_formats, formats)
end

def put_layout_formats(%Plug.Conn{}, _formats), do: raise(AlreadySentError)
def put_layout_formats(%Plug.Conn{} = conn, _formats) do
raise(AlreadySentError, """
the response was already sent.

Status code: #{conn.status}
Request path: #{conn.request_path}
Method: #{conn.method}
""")
end

@doc """
Retrieves current layout formats.
Expand Down
11 changes: 10 additions & 1 deletion test/phoenix/controller/controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,16 @@ defmodule Phoenix.Controller.ControllerTest do
conn = put_format(conn, "print")
assert layout(conn) == {AppView, :print}

assert_raise Plug.Conn.AlreadySentError, fn ->
message = """
the response was already sent.

Status code: 200
Request path: /
Method: GET
Layout: {AppView, :print}
"""

assert_raise Plug.Conn.AlreadySentError, message, fn ->
put_layout(sent_conn(), {AppView, :print})
end
end
Expand Down