fix: prevent sendStartGameMsg from crashing server on client disconnect (#3939)

The catch block in sendStartGameMsg() re-throws the error, which means a
single client's WebSocket failure (e.g. disconnected during game start)
propagates up and can crash the entire game server. The start() method
calls sendStartGameMsg() in a forEach loop over all clients, so one bad
client kills the game for everyone.

Changes:
- Added readyState check before sending
- Replaced re-throw with structured error logging
- A single client failure now logs the error and continues gracefully

If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)

## Description:

Describe the PR.

## 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:

DISCORD_USERNAME
This commit is contained in:
Berk
2026-05-16 21:20:18 +03:00
committed by GitHub
parent 48b957c297
commit 749f496318
+11 -8
View File
@@ -783,6 +783,13 @@ export class GameServer {
});
try {
if (ws.readyState !== WebSocket.OPEN) {
this.log.warn(`WebSocket not open, skipping start message`, {
clientID: client.clientID,
readyState: ws.readyState,
});
return;
}
ws.send(
JSON.stringify({
type: "start",
@@ -793,14 +800,10 @@ export class GameServer {
} satisfies ServerStartGameMessage),
);
} catch (error) {
// can be enabled once we can use {cause: error} in Error constructor starting with ES2022
// eslint-disable-next-line preserve-caught-error
throw new Error(
`error sending start message for game ${this.id}, ${error}`.substring(
0,
250,
),
);
this.log.error(`error sending start message for game ${this.id}`, {
clientID: client.clientID,
error: error instanceof Error ? error.message : String(error),
});
}
}