Erlang channels following example in docs given Error

A connection can be made between the client and the server but whenever Isend a message from the client I get the error below

In the roomchannel module

def join("room:lobby", _message, socket) do 
  IO.puts("This is a test")
  {:ok, socket}
end

def handle_in("new_msg", %{"body" => body}, socket) do 
  broadcast ! socket, "new_msg", %{body: body}
  {:noreply, socket}
end

def join("room:" <> _private_room_id, _params, _socket) do
  {:error, %{reason: "unauthorized"}}
end
** (FunctionClauseError) no function clause matching in Phoenix.Channel.assert_joined!/1
(phoenix) lib/phoenix/channel.ex:495: Phoenix.Channel.assert_joined!(false)
(phoenix) lib/phoenix/channel.ex:394: Phoenix.Channel.broadcast/3
(rialto_web_console) lib/rialto_web_console_web/channels/room_channel.ex:10: RialtoWebConsoleWeb.RoomChannel.handle_in/3
(phoenix) lib/phoenix/channel/server.ex:244: anonymous fn/4 in Phoenix.Channel.Server.handle_info/2
(rialto_web_console) lib/rialto_web_console_web/endpoint.ex:1: RialtoWebConsoleWeb.Endpoint.instrument/4
(stdlib) gen_server.erl:601: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:667: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{event: "new_msg", join_ref: "2", payload: %{"body" => "this is a test"}, ref: "3", topic: "room:lobby"}
State: %Phoenix.Socket{assigns: %{}, channel: RialtoWebConsoleWeb.RoomChannel, channel_pid: #PID<0.353.0>, endpoint: RialtoWebConsoleWeb.Endpoint, handler: RialtoWebConsoleWeb.UserSocket, id: nil, join_ref: "2", joined: true, private: %{log_handle_in: :debug, log_join: :info}, pubsub_server: RialtoWebConsole.PubSub, ref: nil, serializer: Phoenix.Transports.V2.WebSocketSerializer, topic: "room:lobby", transport: Phoenix.Transports.WebSocket, transport_name: :websocket, transport_pid: #PID<0.346.0>, vsn: "2.0.0"}
def handle_in("new_msg", %{"body" => body}, socket) do 
  broadcast ! socket, "new_msg", %{body: body}
 #~~~~~~~~~~^
  {:noreply, socket}
end

I think it should be broadcast! socket, "new_msg", %{body: body}.

1 Like

I am not sure it is a good idea to separate joins… They should be grouped.
The error is for a no function clause matching

def join("room:lobby", _message, socket) do 
  IO.puts("This is a test")
  {:ok, socket}
end

def join("room:" <> _private_room_id, _params, _socket) do
  {:error, %{reason: "unauthorized"}}
end

def handle_in("new_msg", %{"body" => body}, socket) do 
  broadcast ! socket, "new_msg", %{body: body}
  {:noreply, socket}
end

I don’t think the incorrect grouping is what’s causing the error though.

I think it’s caused by ! negating the struct.

iex(1)> ! %Phoenix.Socket{}
false

So, broadcast ! socket, "new_msg", %{body: body} is doing broadcast false, "new_msg", %{body: body} which causes the assert_joined! to fail to match, since it expects a struct.

1 Like

It’s also true that broadcast ! is wrong… :slight_smile:

My advice was on grouping functions of the same type, as it is also not recommended to mix handle_call and handle_cast, handle_in and handle_info etc.

But your advice might be the solution.