Forward game tick errors from worker to client 🐛 (#3690)

## Description:

Currently there is a "Game tick error: Invalid coordinates: NaN,NaN"
error which crashes the game rarely.
Maybe introduced by water nukes, I'm not sure.
To properly debug it when it happens again, lets print the stacktrace:

- Game tick errors (`ErrorUpdate`) were silently dropped in the web
worker's `drain()` function, so the client's error modal never displayed
- Added a `"game_error"` worker message type to forward `ErrorUpdate`
from the worker to the main thread
- The client now receives the full error message and stack trace via the
existing `showErrorModal` dialog

<img width="1147" height="402" alt="image"
src="https://github.com/user-attachments/assets/1b5dcc02-2903-41c9-bf0e-75f22cb7811a"
/>

## Please complete the following:

- [X] I have added screenshots for all UI updates
- [X] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [X] I have added relevant tests to the test directory
- [X] 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:

FloPinguin
This commit is contained in:
FloPinguin
2026-04-16 06:03:01 +02:00
committed by GitHub
parent e0cc50d3c4
commit 87a72a4e93
3 changed files with 16 additions and 1 deletions
+3
View File
@@ -60,6 +60,9 @@ async function drain(): Promise<void> {
const batch: GameUpdateViewData[] = [];
const onTickUpdate = (gu: GameUpdateViewData | ErrorUpdate) => {
if (!("updates" in gu)) {
if ("errMsg" in gu) {
sendMessage({ type: "game_error", error: gu } as WorkerMessage);
}
return;
}
batch.push(gu);
+5
View File
@@ -53,6 +53,11 @@ export class WorkerClient {
}
}
break;
case "game_error":
if (this.gameUpdateCallback && message.error) {
this.gameUpdateCallback(message.error);
}
break;
case "initialized":
default:
+8 -1
View File
@@ -7,7 +7,7 @@ import {
PlayerProfile,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { GameUpdateViewData } from "../game/GameUpdates";
import { ErrorUpdate, GameUpdateViewData } from "../game/GameUpdates";
import { ClientID, GameStartInfo, Turn } from "../Schemas";
export type WorkerMessageType =
@@ -16,6 +16,7 @@ export type WorkerMessageType =
| "turn"
| "game_update"
| "game_update_batch"
| "game_error"
| "player_actions"
| "player_actions_result"
| "player_buildables"
@@ -62,6 +63,11 @@ export interface GameUpdateBatchMessage extends BaseWorkerMessage {
gameUpdates: GameUpdateViewData[];
}
export interface GameErrorMessage extends BaseWorkerMessage {
type: "game_error";
error: ErrorUpdate;
}
export interface PlayerActionsMessage extends BaseWorkerMessage {
type: "player_actions";
playerID: PlayerID;
@@ -147,6 +153,7 @@ export type WorkerMessage =
| InitializedMessage
| GameUpdateMessage
| GameUpdateBatchMessage
| GameErrorMessage
| PlayerActionsResultMessage
| PlayerBuildablesResultMessage
| PlayerProfileResultMessage