-
-
Notifications
You must be signed in to change notification settings - Fork 90
Bug: handle_event("next_round") always executes unconditional DB fetch and broadcast — intermediate returns are dead code #2632
Copy link
Copy link
Open
Description
Describe the bug
In player_live/show.ex, handle_event("next_round", ...) contains two early {:noreply, ...} returns inside the if round_open? branches. Because these are not the last expression in the function, Elixir discards them. The function always falls through to the unconditional Game.find + Endpoint.broadcast at the end.
Affected file
copi.owasp.org/lib/copi_web/live/player_live/show.ex
Code snippet
def handle_event("next_round", _, socket) do
game = socket.assigns.game
if round_open?(game) do
if Copi.Cornucopia.Game.can_continue_round?(game) do
Copi.Cornucopia.update_game(game, %{round_open: false})
Process.send_after(self(), :proceed_to_next_round, 100)
{:noreply, assign(socket, :game, game)} # ← ignored; not the last expression
else
{:noreply, socket} # ← ignored; not the last expression
end
else
Copi.Cornucopia.update_game(game, %{rounds_played: game.rounds_played + 1, round_open: true})
...
end
# These always execute, regardless of which branch was taken above
{:ok, updated_game} = Game.find(game.id)
CopiWeb.Endpoint.broadcast(topic(updated_game.id), "game:updated", updated_game)
{:noreply, assign(socket, :game, updated_game)}
endImpact
- When the round can't close yet (
round_open? && !can_continue?), the handler is supposed to be a no-op, but it still executes aGame.findDB query and broadcasts agame:updatedPubSub message to all connected players — causing unnecessary load and spurious UI reloads. - The intended early returns are dead code and will never be the actual function return value.
Expected behavior
When no state change occurs (round is open and cannot yet continue), the handler should return {:noreply, socket} immediately with no DB query and no broadcast.
Proposed fix
Restructure the handler so each branch is a complete, independent case/cond arm that returns its own {:noreply, ...} including the appropriate fetch and broadcast only when a state change actually occurred.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels