Skip to content

Commit 2918a0b

Browse files
authored
Fix error return when the value is a struct (#1381)
When returning a struct implementing to_string an exception will be thrown on Enum.to_list, because structs passes the is_map/1 gaurd and Enum.to_list fails on structs. In these cases it needs to fall back to to_string. In Elixir 1.17 we can use is_non_struct_map/1, but think it won't be worth updating the minimum Elixir version for this.
1 parent 01e8e4b commit 2918a0b

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

lib/absinthe/phase/document/execution/resolution.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ defmodule Absinthe.Phase.Document.Execution.Resolution do
409409
end
410410
end
411411

412-
defp split_error_value(error_value) when is_list(error_value) or is_map(error_value) do
412+
defp split_error_value(error_value)
413+
when is_list(error_value) or (is_map(error_value) and not is_struct(error_value)) do
413414
Keyword.split(Enum.to_list(error_value), [:message, :path])
414415
end
415416

test/absinthe/resolution_test.exs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ defmodule Absinthe.ResolutionTest do
3030
field :invalid_resolver, :string do
3131
resolve("bogus")
3232
end
33+
34+
field :map_resolver, :string do
35+
resolve fn _, _ ->
36+
{:error, %{message: "map"}}
37+
end
38+
end
39+
40+
field :struct_resolver, :string do
41+
resolve fn _, _ ->
42+
# we are using the Date struct here, but it can be any struct
43+
# with an implementation for String.Chars
44+
{:error, ~D[2025-01-01]}
45+
end
46+
end
3347
end
3448
end
3549

@@ -77,4 +91,28 @@ defmodule Absinthe.ResolutionTest do
7791
{:ok, _} = Absinthe.run(doc, Schema)
7892
end
7993
end
94+
95+
test "resolves error with map value" do
96+
doc = """
97+
{ mapResolver }
98+
"""
99+
100+
assert {:ok,
101+
%{
102+
data: %{"mapResolver" => nil},
103+
errors: [%{message: "map"}]
104+
}} = Absinthe.run(doc, Schema)
105+
end
106+
107+
test "resolves error with struct value implementing String.Chars" do
108+
doc = """
109+
{ structResolver }
110+
"""
111+
112+
assert {:ok,
113+
%{
114+
data: %{"structResolver" => nil},
115+
errors: [%{message: "2025-01-01"}]
116+
}} = Absinthe.run(doc, Schema)
117+
end
80118
end

0 commit comments

Comments
 (0)