Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
50 changes: 42 additions & 8 deletions lib/elixir/lib/exception.ex
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ defmodule Exception do
end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mark it as @doc false. Preferably underscore it too.

@spec format(String.t(), any) :: String.t()
def format_message_with_term(message, term) do
inspected =
term
|> inspect(pretty: true)
|> String.replace(~r/^(?=.+)/m, " ")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to achieve this by splitting on new lines and indenting every non empty string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add padding option to inspect at some point.


message <> "\n\n" <> inspected
end

@doc """
Attaches information to exceptions for extra debugging.

Expand Down Expand Up @@ -1431,7 +1441,10 @@ defmodule BadStructError do

@impl true
def message(exception) do
"expected a struct named #{inspect(exception.struct)}, got: #{inspect(exception.term)}"
Exception.format_message_with_term(
"expected a struct named #{inspect(exception.struct)}, got:",
exception.term
)
end
end

Expand All @@ -1451,7 +1464,10 @@ defmodule BadMapError do

@impl true
def message(exception) do
"expected a map, got: #{inspect(exception.term)}"
Exception.format_message_with_term(
"expected a map, got:",
exception.term
)
end
end

Expand All @@ -1470,7 +1486,10 @@ defmodule BadBooleanError do

@impl true
def message(exception) do
"expected a boolean on left-side of \"#{exception.operator}\", got: #{inspect(exception.term)}"
Exception.format_message_with_term(
"expected a boolean on left-side of \"#{exception.operator}\", got:",
exception.term
)
end
end

Expand All @@ -1492,7 +1511,10 @@ defmodule MatchError do

@impl true
def message(exception) do
"no match of right hand side value: #{inspect(exception.term)}"
Exception.format_message_with_term(
"no match of right hand side value:",
exception.term
)
end
end

Expand All @@ -1518,7 +1540,10 @@ defmodule CaseClauseError do

@impl true
def message(exception) do
"no case clause matching: #{inspect(exception.term)}"
Exception.format_message_with_term(
"no case clause matching:",
exception.term
)
end
end

Expand Down Expand Up @@ -1548,7 +1573,10 @@ defmodule WithClauseError do

@impl true
def message(exception) do
"no with clause matching: #{inspect(exception.term)}"
Exception.format_message_with_term(
"no with clause matching:",
exception.term
)
end
end

Expand Down Expand Up @@ -1598,7 +1626,10 @@ defmodule TryClauseError do

@impl true
def message(exception) do
"no try clause matching: #{inspect(exception.term)}"
Exception.format_message_with_term(
"no try clause matching:",
exception.term
)
end
end

Expand Down Expand Up @@ -2160,7 +2191,10 @@ defmodule KeyError do
"make sure to add parentheses after the function name)"

true ->
message <> " in: #{inspect(term, pretty: true, limit: :infinity)}"
Exception.format_message_with_term(
message <> " in:",
term
)
end
end

Expand Down
11 changes: 6 additions & 5 deletions lib/elixir/test/elixir/exception_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -701,33 +701,34 @@ defmodule ExceptionTest do
message = blame_message(%{first: nil, second: nil}, fn map -> map.firts end)

assert message == """
key :firts not found in: %{first: nil, second: nil}. Did you mean:
key :firts not found in:\n\n %{first: nil, second: nil}. Did you mean:

* :first
"""

message = blame_message(%{"first" => nil, "second" => nil}, fn map -> map.firts end)

assert message == "key :firts not found in: %{\"first\" => nil, \"second\" => nil}"
assert message == "key :firts not found in:\n\n %{\"first\" => nil, \"second\" => nil}"

message =
blame_message(%{"first" => nil, "second" => nil}, fn map -> Map.fetch!(map, "firts") end)

assert message == "key \"firts\" not found in: %{\"first\" => nil, \"second\" => nil}"
assert message ==
"key \"firts\" not found in:\n\n %{\"first\" => nil, \"second\" => nil}"

message =
blame_message([first: nil, second: nil], fn kwlist -> Keyword.fetch!(kwlist, :firts) end)

assert message == """
key :firts not found in: [first: nil, second: nil]. Did you mean:
key :firts not found in:\n\n [first: nil, second: nil]. Did you mean:

* :first
"""
end

test "annotates key error with suggestions for structs" do
message = blame_message(%URI{}, fn map -> map.schema end)
assert message =~ "key :schema not found in: %URI{"
assert message =~ "key :schema not found in:\n\n %URI{"
assert message =~ "Did you mean:"
assert message =~ "* :scheme"
end
Expand Down
22 changes: 13 additions & 9 deletions lib/elixir/test/elixir/kernel/raise_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -450,16 +450,20 @@ defmodule Kernel.RaiseTest do
end

test "badmatch error" do
x = :example

result =
try do
^x = Process.get(:unused, 0)
[] = Range.to_list(1000_000..1_000_009)
rescue
x in [MatchError] -> Exception.message(x)
end

assert result == "no match of right hand side value: 0"
assert result ==
"""
no match of right hand side value:

[1000000, 1000001, 1000002, 1000003, 1000004, 1000005, 1000006, 1000007,
1000008, 1000009]\
"""
end

test "bad key error" do
Expand All @@ -479,7 +483,7 @@ defmodule Kernel.RaiseTest do
x in [KeyError] -> Exception.message(x)
end

assert result == "key :foo not found in: %{}"
assert result == "key :foo not found in:\n\n %{}"
end

test "bad map error" do
Expand All @@ -490,7 +494,7 @@ defmodule Kernel.RaiseTest do
x in [BadMapError] -> Exception.message(x)
end

assert result == "expected a map, got: 0"
assert result == "expected a map, got:\n\n 0"
end

test "bad boolean error" do
Expand All @@ -501,7 +505,7 @@ defmodule Kernel.RaiseTest do
x in [BadBooleanError] -> Exception.message(x)
end

assert result == "expected a boolean on left-side of \"and\", got: 1"
assert result == "expected a boolean on left-side of \"and\", got:\n\n 1"
end

test "case clause error" do
Expand All @@ -516,7 +520,7 @@ defmodule Kernel.RaiseTest do
x in [CaseClauseError] -> Exception.message(x)
end

assert result == "no case clause matching: 0"
assert result == "no case clause matching:\n\n 0"
end

test "cond clause error" do
Expand Down Expand Up @@ -550,7 +554,7 @@ defmodule Kernel.RaiseTest do
x in [TryClauseError] -> Exception.message(x)
end

assert result == "no try clause matching: :example"
assert result == "no try clause matching:\n\n :example"
end

test "undefined function error as Erlang error" do
Expand Down
2 changes: 1 addition & 1 deletion lib/elixir/test/elixir/kernel/with_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ defmodule Kernel.WithTest do
end

test "else conditions with match error" do
assert_raise WithClauseError, "no with clause matching: :error", fn ->
assert_raise WithClauseError, "no with clause matching:\n\n :error", fn ->
with({:ok, res} <- error(), do: res, else: ({:error, error} -> error))
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/elixir/test/elixir/keyword_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ defmodule KeywordTest do
assert Keyword.replace!([a: 1, b: 2, a: 3, b: 4], :a, 1) == [a: 1, b: 2, b: 4]
assert Keyword.replace!([a: 1, b: 2, c: 3, b: 4], :b, :new) == [a: 1, b: :new, c: 3]

assert_raise KeyError, "key :b not found in: []", fn ->
assert_raise KeyError, "key :b not found in:\n\n []", fn ->
Keyword.replace!([], :b, :new)
end

assert_raise KeyError, "key :c not found in: [a: 1, b: 2, a: 3]", fn ->
assert_raise KeyError, "key :c not found in:\n\n [a: 1, b: 2, a: 3]", fn ->
Keyword.replace!([a: 1, b: 2, a: 3], :c, :new)
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/elixir/test/elixir/map_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,11 @@ defmodule MapTest do
assert Map.replace!(map, :b, 10) == %{c: 3, b: 10, a: 1}
assert Map.replace!(map, :a, 1) == map

assert_raise KeyError, ~r/key :x not found in: %{.*a: 1.*}/, fn ->
assert_raise KeyError, ~r/key :x not found in:\n\n %{.*a: 1.*}/, fn ->
Map.replace!(map, :x, 10)
end

assert_raise KeyError, "key :x not found in: %{}", fn ->
assert_raise KeyError, "key :x not found in:\n\n %{}", fn ->
Map.replace!(%{}, :x, 10)
end
end
Expand Down