Skip to content

Commit

Permalink
Move value in protocol errors to its own line (#14003)
Browse files Browse the repository at this point in the history
  • Loading branch information
davydog187 authored Nov 21, 2024
1 parent 50619b1 commit 2f844fd
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 21 deletions.
19 changes: 17 additions & 2 deletions lib/elixir/lib/exception.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1997,8 +1997,23 @@ defmodule Protocol.UndefinedError do

@impl true
def message(%{protocol: protocol, value: value, description: description}) do
"protocol #{inspect(protocol)} not implemented for #{inspect(value)} of type " <>
value_type(value) <> maybe_description(description) <> maybe_available(protocol)
inspected =
value
|> inspect(pretty: true)
# Indent only lines with contents on them
|> String.replace(~r/^(?=.+)/m, " ")

"protocol #{inspect(protocol)} not implemented for type " <>
value_type(value) <>
maybe_description(description) <>
maybe_available(protocol) <>
"""
Got value:
#{inspected}
"""
end

defp value_type(%{__struct__: struct}), do: "#{inspect(struct)} (a struct)"
Expand Down
30 changes: 21 additions & 9 deletions lib/elixir/test/elixir/inspect_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -526,16 +526,20 @@ defmodule Inspect.MapTest do
# Inspect.Error is raised here when we tried to print the error message
# called by another exception (Protocol.UndefinedError in this case)
exception_message = ~s'''
protocol Enumerable not implemented for #Inspect.Error<
got ArgumentError with message:
protocol Enumerable not implemented for type Inspect.MapTest.Failing (a struct)
"""
errors were found at the given arguments:
Got value:
* 1st argument: not an atom
"""
#Inspect.Error<
got ArgumentError with message:
while inspecting:
"""
errors were found at the given arguments:
* 1st argument: not an atom
"""
while inspecting:
'''

Expand Down Expand Up @@ -926,7 +930,11 @@ defmodule Inspect.CustomProtocolTest do
got Protocol.UndefinedError with message:
"""
protocol Inspect.CustomProtocolTest.CustomInspect not implemented for %Inspect.CustomProtocolTest.MissingImplementation{} of type Inspect.CustomProtocolTest.MissingImplementation (a struct)
protocol Inspect.CustomProtocolTest.CustomInspect not implemented for type Inspect.CustomProtocolTest.MissingImplementation (a struct)
Got value:
%Inspect.CustomProtocolTest.MissingImplementation{}
"""
while inspecting:
Expand All @@ -953,7 +961,11 @@ defmodule Inspect.CustomProtocolTest do
got Protocol.UndefinedError with message:
"""
protocol Inspect.CustomProtocolTest.CustomInspect not implemented for %Inspect.CustomProtocolTest.MissingImplementation{} of type Inspect.CustomProtocolTest.MissingImplementation (a struct)
protocol Inspect.CustomProtocolTest.CustomInspect not implemented for type Inspect.CustomProtocolTest.MissingImplementation (a struct)
Got value:
%Inspect.CustomProtocolTest.MissingImplementation{}
"""
while inspecting:
Expand Down
5 changes: 3 additions & 2 deletions lib/elixir/test/elixir/protocol/consolidation_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,9 @@ defmodule Protocol.ConsolidationTest do

test "protocol not implemented" do
message =
"protocol Protocol.ConsolidationTest.Sample not implemented for :foo of type Atom. " <>
"This protocol is implemented for the following type(s): Protocol.ConsolidationTest.ImplStruct"
"protocol Protocol.ConsolidationTest.Sample not implemented for type Atom. " <>
"This protocol is implemented for the following type(s): Protocol.ConsolidationTest.ImplStruct" <>
"\n\nGot value:\n\n :foo\n"

assert_raise Protocol.UndefinedError, message, fn ->
sample = String.to_atom("Elixir.Protocol.ConsolidationTest.Sample")
Expand Down
9 changes: 8 additions & 1 deletion lib/elixir/test/elixir/protocol_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,14 @@ defmodule ProtocolTest do
end

test "protocol not implemented" do
message = "protocol ProtocolTest.Sample not implemented for :foo of type Atom"
message =
"""
protocol ProtocolTest.Sample not implemented for type Atom
Got value:
:foo
"""

assert_raise Protocol.UndefinedError, message, fn ->
sample = String.to_atom("Elixir.ProtocolTest.Sample")
Expand Down
31 changes: 24 additions & 7 deletions lib/elixir/test/elixir/string/chars_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -105,39 +105,54 @@ defmodule String.Chars.ErrorsTest do

test "bitstring" do
message =
"protocol String.Chars not implemented for <<0, 1::size(4)>> of type BitString, cannot convert a bitstring to a string"
"""
protocol String.Chars not implemented for type BitString, cannot convert a bitstring to a string
Got value:
<<0, 1::size(4)>>
"""

assert_raise Protocol.UndefinedError, message, fn ->
to_string(<<1::size(12)-integer-signed>>)
end
end

test "tuple" do
message = "protocol String.Chars not implemented for {1, 2, 3} of type Tuple"
message = """
protocol String.Chars not implemented for type Tuple
Got value:
{1, 2, 3}
"""

assert_raise Protocol.UndefinedError, message, fn ->
to_string({1, 2, 3})
end
end

test "PID" do
message = ~r"^protocol String\.Chars not implemented for #PID<.+?> of type PID$"
message =
~r"^protocol String\.Chars not implemented for type PID\n\nGot value:\n\n #PID<.+?>$"

assert_raise Protocol.UndefinedError, message, fn ->
to_string(self())
end
end

test "ref" do
message = ~r"^protocol String\.Chars not implemented for #Reference<.+?> of type Reference$"
message =
~r"^protocol String\.Chars not implemented for type Reference\n\nGot value:\n\n #Reference<.+?>$"

assert_raise Protocol.UndefinedError, message, fn ->
to_string(make_ref()) == ""
end
end

test "function" do
message = ~r"^protocol String\.Chars not implemented for #Function<.+?> of type Function$"
message =
~r"^protocol String\.Chars not implemented for type Function\n\nGot value:\n\n #Function<.+?>$"

assert_raise Protocol.UndefinedError, message, fn ->
to_string(fn -> nil end)
Expand All @@ -146,7 +161,9 @@ defmodule String.Chars.ErrorsTest do

test "port" do
[port | _] = Port.list()
message = ~r"^protocol String\.Chars not implemented for #Port<.+?> of type Port$"

message =
~r"^protocol String\.Chars not implemented for type Port\n\nGot value:\n\n #Port<.+?>$"

assert_raise Protocol.UndefinedError, message, fn ->
to_string(port)
Expand All @@ -155,7 +172,7 @@ defmodule String.Chars.ErrorsTest do

test "user-defined struct" do
message =
"protocol String\.Chars not implemented for %String.Chars.ErrorsTest.Foo{foo: \"bar\"} of type String.Chars.ErrorsTest.Foo (a struct)"
"protocol String\.Chars not implemented for type String.Chars.ErrorsTest.Foo (a struct)\n\nGot value:\n\n %String.Chars.ErrorsTest.Foo{foo: \"bar\"}\n"

assert_raise Protocol.UndefinedError, message, fn ->
to_string(%Foo{})
Expand Down

0 comments on commit 2f844fd

Please sign in to comment.