LiveView's `ArgumentError` makes the actual errors harder to debug


I noticed that when an error in my logic bubble ups, it leads to an ArgumentError in LiveView and that makes debugging the actual error a bit more tedious because it’s all formatted as a single error. Here’s an example:

[error] #PID<0.838.0> running Phoenix.Endpoint.SyncCodeReloadPlug (connection #PID<0.809.0>, stream id 2) terminated
Server: localhost:4000 (http)
Request: GET /
** (exit) an exception was raised:
    ** (ArgumentError) assign/3 expects a socket from Phoenix.LiveView/Phoenix.LiveComponent  or an assigns map from Phoenix.Component as first argument, got: %{reason: %KeyError{key: :acount, term: #Glossia.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 1, email: "", confirmed_at: nil, credentials: #Ecto.Association.NotLoaded<association :credentials is not loaded>, account_id: 1, account: #Ecto.Association.NotLoaded<association :account is not loaded>, organizations: #Ecto.Association.NotLoaded<association :organizations is not loaded>, inserted_at: ~N[2023-07-20 17:38:49], updated_at: ~N[2023-07-20 17:38:49], ...>, message: nil}, status: 500, stack: [{GlossiaWeb.MarketingHTML, :"-index_app/1-fun-0-", 2, [file: ~c"lib/glossia_web/controllers/marketing_html/app/index.heex"

I wonder if it might have something to do with my configuration.

I suspect it’s a missing socket someplace in the “error” branch of the code - the error message indicates that assign is being handed a map with keys :reason, :status, and stack in its first argument.


A bigger question is: if you want precise error messages, why are you rescuing KeyError and then manually trying to return an HTTP 500?

Thanks @al2o3cr for your answer. It shed some light around what the issue might be. It turns out that I had the following in an error layout:

defmodule GlossiaWeb.ErrorHTML do
  use GlossiaWeb, :html

  def render(template, assigns) do
    assigns = assign(assigns, :foo, "bar")
    <div><%= @foo %></div>

I was expecting that second argument of the function to be an assigns because that’s what the documentation says, but it turns out it’s the internal error raised by Phoenix. Because I was calling assign with an unexpected type that was causing the error that I pasted above.