Seeing multiple handle_event("...", %{"..." => "..."}, %Phoenix.LiveView.Socket{...}) coming from random components/events

phoenix liveview version: 0.20

we’ve had a long-standing issue in production with the only backtrace from our code being

lib/scorpion_web/components/activity/carousel.ex:5
ScorpionWeb.CarouselComponent.handle_event("...", %{"..." => [...], "..." => 
%{"..." => "..."}}, %Phoenix.LiveView.Socket{...})

where line 5 is

  def handle_event("toggle_mute_carousel", _params, %{} = socket) do
    muted = Map.get(socket.assigns, :muted, true)
    {:noreply, assign(socket, muted: !muted)}
  end

and the parameters sent are from a form submission in a completely different component

{
  "_target": [
    "filter_form",
    "query"
  ],
  "filter_form": {
    "query": "United States"
  }
}

or another example

lib/scorpion_web/components/activity/availability_wrap.ex:792
ScorpionWeb.AvailabilityWrapComponent.handle_event("...",
%{"..." => "..."}, %Phoenix.LiveView.Socket{...})

where line 792 is

  def handle_event("show_full_availability_calendar", %{"date" => date_string}, socket) do
    date = Date.from_iso8601!(date_string)

    socket =
      assign(socket, %{
        selected_date: date,
        preview_calendar: false
      })
      |> enqueue_async_availability_call()

    {:noreply, socket}
  end

sometimes the parameters have nothing to do with the event or component in question, and the error always shows the empty "..." handle_event.

i am not able to reproduce this error locally, unfortunately. has anyone seen this before?

It sounds like your error service isn’t fully setup in your app. With AppSignal, for example, you need to call Appsignal.Phoenix.LiveView.attach() in your application’s start/2 function. If it’s not that I’m unsure, but we forgot this line and that’s exactly what the stack traces looked like for us!

hmm… unfortunately we do already have that in our start_function :confused:

  alias Appsignal.Phoenix.LiveView, as: AppsignalLiveView

  def start(_type, _args) do
    AppsignalLiveView.attach()

    # List all child processes to be supervised
    children = [
      ScorpionWeb.Telemetry,
      {Phoenix.PubSub, name: Scorpion.PubSub},
      # Start the endpoint when the application starts
      ScorpionWeb.Endpoint,
      Scorpion.Repo,
      {Task.Supervisor, name: ScorpionWeb.TaskSupervisor},
      %{
        id: :my_cache_id,
        start: {Cachex, :start_link, [:data, [expiration: expiration(default: Application.get_env(:scorpion, :cache_ttl_ms))]]}
      },
      {Redix, {Application.fetch_env!(:scorpion, :redis_host), [name: :redix]}},
      {Segment, Application.get_env(:scorpion, :segment_key)},
      {Plug.Cowboy.Drainer, refs: :all, shutdown: 60_000},
      {Oban, Application.fetch_env!(:scorpion, Oban)}
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: Scorpion.Supervisor]
    Supervisor.start_link(children, opts)
  end

Ah dang, sorry I couldn’t be of any help. Did you figure it out?

that’s okay, appreciate it! i did not. may have to file an issue or something.

2 Likes

I think I may do the same I was just looking at an error where it yet again was showing "..." :face_with_spiral_eyes: Was sure we were seeing params for a bit there.

yea it’s a little puzzling the name of the event isn’t even being sent… i guess the line is pointing to a specific event, so i’m wondering if it’s more of an appsignal issue, a phoenix issue, or some weird combination of both

We had a patch in LV 1.0.0-rc.5 that may fix this:

  • Fix form recovery when targeting LiveComponent
2 Likes

thanks, Chris! i’ll give this a shot.

Heyya! We are on latest LV RC now and still saw the error and I dug in. What I found is that we had 2 forms doing this:

 phx-change={JS.push("validate_filter_form", target: @myself)}

which is identical to

 phx-target={@myself}
 phx-change="validate_filter_form"

The latter works w/ the auto-recovering but the former sends, in place of validate_filter_form for the first arg to handle_event a different payload due to the use of JS.push.

Obviously trivial for us to flip to a clean string (which we are moving live as we speak) but I am passing this along in case you have any thoughts/concerns on it!

Thanks, as always!

1 Like

Hey @coladarci,

this should be fixed by evaluate js commands during form recovery by SteffenDE · Pull Request #3608 · phoenixframework/phoenix_live_view · GitHub. Included since LV 1.0.2!