Channels handle_in/3 error

I have a room channel where I have defined a handle_in function like this

  @impl true
  def join("room:" <> room_id, _payload, socket) do
   {:ok, %{channel: "room:#{room_id}"}, assign(socket, :room_id, room_id)}
  end

  # def handle_in("shout", payload, socket) do
  #   broadcast socket, "shout", payload
  #   {:noreply, socket}
  # end

  def handle_in("message:add", %{"message" => body}, socket) do
    room_id = socket.assigns[:room_id]
    broadcast!(socket, "room:#{room_id}:new_message", %{body: body})
    {:reply, :ok, socket}
  end

and I’m getting this error when I’m trying to send a message through the client. I’m pretty sure this is not the error from the client-side but in case if anyone wants to look please let me know.

[error] GenServer #PID<0.1241.0> terminating
** (FunctionClauseError) no function clause matching in ChatApiWeb.RoomChannel.handle_in/3
    (chat_api 0.1.0) lib/chat_api_web/channels/room_channel.ex:14: ChatApiWeb.RoomChannel.handle_in("message:add", "dadad", %Phoenix.Socket{assigns: %{room_id: "1"}, channel: ChatApiWeb.RoomChannel, channel_pid: #PID<0.1241.0>, endpoint: ChatApiWeb.Endpoint, handler: ChatApiWeb.UserSocket, id: nil, join_ref: "3", joined: true, private: %{log_handle_in: :debug, log_join: :info}, pubsub_server: ChatApi.PubSub, ref: "4", serializer: Phoenix.Socket.V2.JSONSerializer, topic: "room:1", transport: :websocket, transport_pid: #PID<0.1238.0>})
    (phoenix 1.5.1) lib/phoenix/channel/server.ex:316: Phoenix.Channel.Server.handle_info/2
    (stdlib 3.12.1) gen_server.erl:637: :gen_server.try_dispatch/4
    (stdlib 3.12.1) gen_server.erl:711: :gen_server.handle_msg/6
    (stdlib 3.12.1) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{event: "message:add", join_ref: "3", payload: "dadad", ref: "4", topic: "room:1"}

How do I debug this to know where I’m doing wrong?

Your clause is matching on %{"message" => body} but your client is only sending the body directly as a string, ChatApiWeb.RoomChannel.handle_in("message:add", "dadad",...) Update the client to send {message: ...} and you should be good

2 Likes

  const sendMessage = event => {
    event.preventDefault();

    if (message) {
      channel.push("message:add", message, () => setMessage(""));
    }
  };

Here you want me to change?

channel.push("message:add", {message: message})
  .receive("ok" => setMessage(""))
2 Likes