Skip to content

fix: add readyState check before endTurn broadcast#3879

Open
berkelmali wants to merge 1 commit intoopenfrontio:mainfrom
berkelmali:fix/readystate-check-endturn
Open

fix: add readyState check before endTurn broadcast#3879
berkelmali wants to merge 1 commit intoopenfrontio:mainfrom
berkelmali:fix/readystate-check-endturn

Conversation

@berkelmali
Copy link
Copy Markdown
Contributor

Description:

Guard ws.send() in endTurn() with a readyState === OPEN check to prevent sending messages to WebSocket connections that have already closed.

Without this guard, broadcasting to a client whose connection closed between ticks can throw an exception and crash the game loop.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

barfires

Guard ws.send() in endTurn() with a readyState === OPEN check
to prevent sending to connections that have already closed.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 7, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c18a93cd-eb1d-4fb5-b215-9c4c337efc92

📥 Commits

Reviewing files that changed from the base of the PR and between 4889cb8 and 97641c0.

📒 Files selected for processing (1)
  • src/server/GameServer.ts

Walkthrough

The pull request adds a readiness check to the endTurn() method in GameServer. Before sending turn update messages to clients, the server now verifies each websocket connection is in an open state, preventing send attempts on closed or closing sockets.

Changes

WebSocket Readiness Validation

Layer / File(s) Summary
Turn Message Broadcast
src/server/GameServer.ts
endTurn() now checks c.ws.readyState before calling c.ws.send(msg), skipping clients whose websocket connections are not open.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

📡 A socket stands ready, or does it not?
Check before you send, catch what's hot!
No more messages lost to the void—
readyState checks keep connections employed.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding a readyState check before broadcasting the endTurn message to prevent sending to closed connections.
Description check ✅ Passed The description clearly explains the problem being fixed (closed WebSocket connections causing exceptions and crashes) and the solution (adding a readyState check), which directly relates to the code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@scamiv
Copy link
Copy Markdown
Contributor

scamiv commented May 7, 2026

Without this guard, broadcasting to a client whose connection closed between ticks can throw an exception and crash the game loop.

I don’t think this claim is accurate. In current ws, send() throws synchronously only for CONNECTING; for CLOSING/CLOSED it goes through sendAfterClose() and returns, and in this call site we do not pass a callback. So this guard is fine as defensive cleanup, but I don’t think it prevents a game-loop crash as described.

if the real concern is “any send to a closed socket may crash or misbehave,” this PR is too narrow. Other sends remain unguarded.
(prestart(), sendStartGameMsg(), kickClient(), and desync messages. sendStartGameMsg() endTurn())

If we want this pattern consistently, a small safeSend() helper instead of adding one-off guards may be the better choice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

2 participants