LiveAdmin crashes when rendering a field that is list of binaries
tmaszk opened this issue · 4 comments
Describe the bug
LiveAdmin crashes when rendering a field that is a list of binaries
To Reproduce
- Define a field on an Ecto resource that is a list of strings
field :home_notifications, {:array, :string}
- Populate the filed on the record with a simple list
["background_check"]
- Try to list the record in LiveAdmin
- See error
Expected behavior
Show the list of binaries
Screenshots
Example console error
[error] GenServer #PID<0.4154.0> terminating
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:safe, [[[60, "p", [], 62, ["background_check"], 60, 47, "p", 62], 10]]} of type Tuple. This protocol is implemented for the following type(s): Atom, BitString, Date, DateTime, Decimal, Explorer.Duration, Float, Floki.Selector, Floki.Selector.AttributeSelector, Floki.Selector.Combinator, Floki.Selector.Functional, Floki.Selector.PseudoClass, Integer, List, NaiveDateTime, Phoenix.LiveComponent.CID, Postgrex.Copy, Postgrex.Query, RemoteIp.Block, Time, URI, Version, Version.Requirement
(elixir 1.15.7) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.15.7) lib/string/chars.ex:22: String.Chars.to_string/1
(elixir 1.15.7) lib/enum.ex:4369: Enum.map_intersperse_list/3
(elixir 1.15.7) lib/enum.ex:1794: Enum.map_join/3
(live_admin 0.11.4) lib/live_admin/components/resource/index.ex:124: anonymous fn/4 in LiveAdmin.Components.Container.Index.render/1
(elixir 1.15.7) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
(live_admin 0.11.4) lib/live_admin/components/resource/index.ex:115: anonymous fn/2 in LiveAdmin.Components.Container.Index.render/1
(elixir 1.15.7) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
(live_admin 0.11.4) lib/live_admin/components/resource/index.ex:103: anonymous fn/2 in LiveAdmin.Components.Container.Index.render/1
(phoenix_live_view 0.20.5) lib/phoenix_live_view/diff.ex:391: Phoenix.LiveView.Diff.traverse/7
(phoenix_live_view 0.20.5) lib/phoenix_live_view/diff.ex:766: Phoenix.LiveView.Diff.render_component/8
(phoenix_live_view 0.20.5) lib/phoenix_live_view/diff.ex:705: Phoenix.LiveView.Diff.zip_components/5
(phoenix_live_view 0.20.5) lib/phoenix_live_view/diff.ex:690: anonymous fn/4 in Phoenix.LiveView.Diff.render_pending_components/6
(stdlib 5.1.1) maps.erl:416: :maps.fold_1/4
(phoenix_live_view 0.20.5) lib/phoenix_live_view/diff.ex:635: Phoenix.LiveView.Diff.render_pending_components/6
(phoenix_live_view 0.20.5) lib/phoenix_live_view/diff.ex:143: Phoenix.LiveView.Diff.render/3
(phoenix_live_view 0.20.5) lib/phoenix_live_view/channel.ex:953: anonymous fn/4 in Phoenix.LiveView.Channel.render_diff/3
(telemetry 1.2.1) /Users/tmaszk/code/colife/deps/telemetry/src/telemetry.erl:321: :telemetry.span/3
(phoenix_live_view 0.20.5) lib/phoenix_live_view/channel.ex:948: Phoenix.LiveView.Channel.render_diff/3
(phoenix_live_view 0.20.5) lib/phoenix_live_view/channel.ex:575: Phoenix.LiveView.Channel.mount_handle_params_result/3
Environment:
- OS: macOS
- Browser: safari
- Version: master or 0.11.4
Additional context
I think the problem is this line
defp render_field(val) when is_list(val), do: Enum.map_join(val, ", ", &render_field/1)
I think it is rendering a field within a field, which is causing the crash. I tried this locally and it worked as I would have expected
defp render_field(val) when is_list(val), do: Enum.map_join(val, ", ", &inspect/1)
Thanks for the report. I do think this was fixed in main in ed13159
I'll backport the fix and release a new version
Just noticed the line you linked is in main, in fact the exact line in that fix. I cannot reproduce this issue in main, only 0.11.4.
Can you double check that you are using main locally when testing (not master)?
Sorry, I didn't refer to the right name for the main branch. I'm able to reproduce the bug on main. I just pulled main and added this one line to test_helper.exs
diff --git a/test/test_helper.exs b/test/test_helper.exs
index 693c803..c482d4e 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -98,6 +98,7 @@ defmodule LiveAdminTest.Post do
@derive {Phoenix.Param, key: :post_id}
schema "posts" do
field(:title, :string)
+ field(:tags, {:array, :string}, default: ["test"])
belongs_to(:user, LiveAdminTest.User, type: :binary_id)
embeds_many(:previous_versions, __MODULE__.Version, on_replace: :delete)
Then when I run the unit tests I get this error:
1) test view resource with associated resource links to user (LiveAdmin.Components.ContainerTest)
test/live_admin/components/container_test.exs:299
** (exit) exited in: Phoenix.LiveViewTest.live("/live_admin_test_post/3")
** (EXIT) an exception was raised:
** (Protocol.UndefinedError) protocol String.Chars not implemented for {:safe, [[[60, "p", [], 62, ["test"], 60, 47, "p", 62], 10]]} of type Tuple
(elixir 1.15.7) lib/string/chars.ex:3: String.Chars.impl_for!/1
(elixir 1.15.7) lib/string/chars.ex:22: String.Chars.to_string/1
(elixir 1.15.7) lib/enum.ex:4369: Enum.map_intersperse_list/3
(elixir 1.15.7) lib/enum.ex:1794: Enum.map_join/3
(live_admin 0.11.4) lib/live_admin/components/resource/view.ex:34: anonymous fn/3 in LiveAdmin.Components.Container.View.render/1
(elixir 1.15.7) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
(live_admin 0.11.4) lib/live_admin/components/resource/view.ex:27: anonymous fn/2 in LiveAdmin.Components.Container.View.render/1
(phoenix_live_view 0.20.3) lib/phoenix_live_view/diff.ex:391: Phoenix.LiveView.Diff.traverse/7
(phoenix_live_view 0.20.3) lib/phoenix_live_view/diff.ex:765: Phoenix.LiveView.Diff.render_component/9
(phoenix_live_view 0.20.3) lib/phoenix_live_view/diff.ex:705: Phoenix.LiveView.Diff.zip_components/5
(phoenix_live_view 0.20.3) lib/phoenix_live_view/diff.ex:690: anonymous fn/4 in Phoenix.LiveView.Diff.render_pending_components/6
(stdlib 4.3.1.3) maps.erl:411: :maps.fold_1/3
(phoenix_live_view 0.20.3) lib/phoenix_live_view/diff.ex:635: Phoenix.LiveView.Diff.render_pending_components/6
(phoenix_live_view 0.20.3) lib/phoenix_live_view/diff.ex:143: Phoenix.LiveView.Diff.render/3
(phoenix_live_view 0.20.3) lib/phoenix_live_view/channel.ex:936: anonymous fn/4 in Phoenix.LiveView.Channel.render_diff/3
(telemetry 1.2.1) /opt/app/deps/telemetry/src/telemetry.erl:321: :telemetry.span/3
(phoenix_live_view 0.20.3) lib/phoenix_live_view/channel.ex:931: Phoenix.LiveView.Channel.render_diff/3
(phoenix_live_view 0.20.3) lib/phoenix_live_view/channel.ex:565: Phoenix.LiveView.Channel.mount_handle_params_result/3
(phoenix_live_view 0.20.3) lib/phoenix_live_view/channel.ex:1152: Phoenix.LiveView.Channel.verified_mount/8
(phoenix_live_view 0.20.3) lib/phoenix_live_view/channel.ex:84: Phoenix.LiveView.Channel.handle_info/2
stacktrace:
(phoenix_live_view 0.20.3) lib/phoenix_live_view/test/live_view_test.ex:400: Phoenix.LiveViewTest.start_proxy/2
test/live_admin/components/container_test.exs:295: LiveAdmin.Components.ContainerTest.__ex_unit_setup_14_0/1
LiveAdmin.Components.ContainerTest.__ex_unit_describe_14/1
That's very helpful, thanks. This should now be fixed in main.