-
-
Notifications
You must be signed in to change notification settings - Fork 81
Open
Description
Describe the bug
In copi.owasp.org/lib/copi_web/live/game_live/show.ex, the handle_info/2 callback that processes game:updated broadcasts always sets requested_round to updated_game.rounds_played + 1 — regardless of whether the game has finished. This contradicts handle_params/3, which correctly uses rounds_played (without +1) for finished games. As a result, any game:updated broadcast received while viewing a finished game summary resets the view to a non-existent round.
Affected file
copi.owasp.org/lib/copi_web/live/game_live/show.ex
Code snippet
# handle_params — CORRECTLY handles finished games (line 24-28):
current_round = if game.finished_at do
game.rounds_played # ← correct: last actual round
else
game.rounds_played + 1 # ← correct: current in-progress round
end
# handle_info — ALWAYS does +1, ignores finished_at (line 48-51):
def handle_info(%{topic: message_topic, event: "game:updated", payload: updated_game}, socket) do
cond do
topic(updated_game.id) == message_topic ->
{:noreply, assign(socket, :game, updated_game) |> assign(:requested_round, updated_game.rounds_played + 1)}
# ↑ BUG: adds +1 even when updated_game.finished_at is set
true ->
{:noreply, socket}
end
endExact failure scenario
- Game finishes with
rounds_played = Nandfinished_atset. handle_paramscorrectly renders the game summary withrequested_round = N.- Any subsequent
game:updatedbroadcast fires (e.g., from a late-arriving player reconnect, the transition broadcast itself, or any other event). handle_infosetsrequested_round = N + 1— a round that does not exist.- The game summary view now tries to show round
N + 1, finds no cards, and renders a blank/broken summary page.
Expected behavior
handle_info should mirror handle_params in how it computes requested_round:
def handle_info(%{topic: message_topic, event: "game:updated", payload: updated_game}, socket) do
cond do
topic(updated_game.id) == message_topic ->
requested_round =
if updated_game.finished_at do
updated_game.rounds_played
else
updated_game.rounds_played + 1
end
{:noreply, assign(socket, :game, updated_game) |> assign(:requested_round, requested_round)}
true ->
{:noreply, socket}
end
endSteps to reproduce
- Create and play a game to completion (all rounds done,
finished_atset). - While on the game summary page (
/games/:game_id), trigger any action that causes agame:updatedbroadcast (or simply wait if there is any background activity). - Observe: the summary page goes blank / shows "round not found" because
requested_roundis now one past the last round.
Additional context
- This is distinct from issue bug: handle_event("next_round") missing early return causes double broadcast and premature game state update #2418, which covers
player_live/show.ex'shandle_event("next_round")double-broadcast bug. - The fix is a one-line-to-five-line change in
handle_infoto mirror theif game.finished_atcheck already present inhandle_params.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels