Skip to content

Commit

Permalink
Merge pull request #1793 from gereon77/introduce-snr-error
Browse files Browse the repository at this point in the history
Introduce SnR error to log the game id
  • Loading branch information
gereon77 authored Jul 27, 2023
2 parents 29eac2c + fa55054 commit fd8a481
Show file tree
Hide file tree
Showing 10 changed files with 39 additions and 24 deletions.
9 changes: 5 additions & 4 deletions agot-bg-game-server/src/common/EntireGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import getElapsedSeconds from "../utils/getElapsedSeconds";
import WildlingCardType from "./ingame-game-state/game-data-structure/wildling-card/WildlingCardType";
import House from "./ingame-game-state/game-data-structure/House";
import { EntireGameSnapshot } from "./ingame-game-state/game-data-structure/Game";
import SnrError from "../utils/snrError";

export enum NotificationType {
READY_TO_START,
Expand Down Expand Up @@ -105,7 +106,7 @@ export default class EntireGame extends GameState<null, LobbyGameState | IngameG
const gameSetup = playerSetups.find(gameSetup => this.gameSettings.playerCount == gameSetup.playerCount);

if (gameSetup == undefined) {
throw new Error(`Invalid playerCount ${this.gameSettings.playerCount} for setupId ${this.gameSettings.setupId}`);
throw new SnrError(this, `Invalid playerCount ${this.gameSettings.playerCount} for setupId ${this.gameSettings.setupId}`);
}

return gameSetup;
Expand Down Expand Up @@ -180,7 +181,7 @@ export default class EntireGame extends GameState<null, LobbyGameState | IngameG
const serializedGameState = _.range(level).reduce((s, _) => s.childGameState, serializedEntireGame as SerializedGameState);

if (!serializedGameState) {
throw new Error();
throw new SnrError(this);
}

return {
Expand Down Expand Up @@ -438,12 +439,12 @@ export default class EntireGame extends GameState<null, LobbyGameState | IngameG

notWaitedPlayers.forEach(p => {
if (!p.liveClockData) {
throw new Error("LiveClockData must be present in doPlayerClocksHandling");
throw new SnrError(this, "LiveClockData must be present in doPlayerClocksHandling");
}

if (p.liveClockData.timerStartedAt) {
if (!p.liveClockData.serverTimer) {
throw new Error("serverTimer must be present in doPlayerClocksHandling");
throw new SnrError(this, "serverTimer must be present in doPlayerClocksHandling");
}

// Stop the timer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import getElapsedSeconds from "../../utils/getElapsedSeconds";
import orders from "./game-data-structure/orders";
import { OrderOnMapProperties, UnitOnMapProperties } from "../../client/MapControls";
import houseCardAbilities from "./game-data-structure/house-card/houseCardAbilities";
import SnrError from "../../utils/snrError";

export const NOTE_MAX_LENGTH = 5000;

Expand Down Expand Up @@ -632,15 +633,15 @@ export default class IngameGameState extends GameState<
const suzerainHouse = this.game.vassalRelations.tryGet(house, null);

if (suzerainHouse == null) {
throw new Error(`getControllerOfHouse(${house.name}) failed as there is no suzerainHouse`);
throw new SnrError(this.entireGame, `getControllerOfHouse(${house.name}) failed as there is no suzerainHouse`);
}

return this.getControllerOfHouse(suzerainHouse);
} else {
const player = this.players.values.find(p => p.house == house);

if (player == null) {
throw new Error(`getControllerOfHouse(${house.name}) failed due to a fatal error`);
throw new SnrError(this.entireGame, `getControllerOfHouse(${house.name}) failed due to a fatal error`);
}

return player;
Expand Down Expand Up @@ -760,7 +761,7 @@ export default class IngameGameState extends GameState<

try {
if (!player.liveClockData) {
throw new Error("LiveClockData must be present in onPlayerClockTimeout");
throw new SnrError(this.entireGame, "LiveClockData must be present in onPlayerClockTimeout");
}

this.endPlayerClock(player, false);
Expand Down Expand Up @@ -944,7 +945,7 @@ export default class IngameGameState extends GameState<
}

if (!newCommander) {
throw new Error("Unable to determine new commander");
throw new SnrError(this.entireGame, "Unable to determine new commander");
}

// It may happen that you replace a player which commands vassals. Assign them to the potential winner.
Expand Down Expand Up @@ -1794,7 +1795,7 @@ export default class IngameGameState extends GameState<

isVassalControlledByPlayer(vassal: House, player: Player): boolean {
if (!this.isVassalHouse(vassal)) {
throw new Error();
throw new SnrError(this.entireGame);
}

return this.game.vassalRelations.tryGet(vassal, null) == player.house;
Expand Down
5 changes: 3 additions & 2 deletions agot-bg-game-server/src/common/ingame-game-state/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import IngameGameState from "./IngameGameState";
import { VoteState } from "./vote-system/Vote";
import { observable } from "mobx";
import getElapsedSeconds, { getTimeDeltaInSeconds } from "../../utils/getElapsedSeconds";
import SnrError from "../../utils/snrError";

export default class Player {
user: User;
Expand All @@ -17,7 +18,7 @@ export default class Player {

get totalRemainingSeconds(): number {
if (!this.liveClockData) {
throw new Error("totalRemainingSeconds requested but no liveClockData present");
throw new SnrError(this.user.entireGame, "totalRemainingSeconds requested but no liveClockData present");
}

let total = this.liveClockData.remainingSeconds;
Expand All @@ -31,7 +32,7 @@ export default class Player {

clientGetTotalRemainingSeconds(now: Date): number {
if (!this.liveClockData) {
throw new Error("totalRemainingSeconds requested but no liveClockData present");
throw new SnrError(this.user.entireGame, "totalRemainingSeconds requested but no liveClockData present");
}

let total = this.liveClockData.remainingSeconds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import BetterMap from "../../../../../../utils/BetterMap";
import ResolveSpymasterGameState, { SerializedResolveSpymasterGameState } from "./resolve-spymaster-game-state/ResolveSpymasterGameState";
import WesterosCard from "../../../../../ingame-game-state/game-data-structure/westeros-card/WesterosCard";
import _ from "lodash";
import SnrError from "../../../../../../utils/snrError";

export default class SpymasterGameState extends GameState<ExecuteLoanGameState,
SimpleChoiceGameState | ResolveSpymasterGameState<SpymasterGameState>> {
Expand Down Expand Up @@ -58,7 +59,7 @@ export default class SpymasterGameState extends GameState<ExecuteLoanGameState,
const concatenatedForCheck = westerosCardsForTopOfDeck.concat(westerosCardsForBottomOfDeck);

if(_.intersection(topTwoCardsOfDeck, concatenatedForCheck).length != topTwoCardsOfDeck.length) {
throw new Error(`Spymaster crashed due to an inconsistent deck ${westerosDeckId}!`);
throw new SnrError(this.entireGame, `Spymaster crashed due to an inconsistent deck ${westerosDeckId}!`);
}

const discardedCards = westerosDeck.filter(wc => wc.discarded);
Expand All @@ -67,7 +68,7 @@ export default class SpymasterGameState extends GameState<ExecuteLoanGameState,

const newWesterosDeck = _.concat(westerosCardsForTopOfDeck, availableCards, westerosCardsForBottomOfDeck, discardedCards);
if (westerosDeck.length != newWesterosDeck.length) {
throw new Error(`Spymaster corrupted deck ${westerosDeckId}`);
throw new SnrError(this.entireGame, `Spymaster corrupted deck ${westerosDeckId}`);
}
this.game.westerosDecks[westerosDeckId] = newWesterosDeck;
// Broadcast manipulated deck for "CoK Westeros Phase Variant"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import AfterWinnerDeterminationGameState from "../AfterWinnerDeterminationGameSt
import _ from "lodash";
import shuffleInPlace from "../../../../../../../../utils/shuffle";
import BetterMap from "../../../../../../../../utils/BetterMap";
import SnrError from "../../../../../../../../utils/snrError";

export default class RodrikTheReaderAbilityGameState extends GameState<
AfterWinnerDeterminationGameState["childGameState"],
Expand Down Expand Up @@ -85,7 +86,7 @@ export default class RodrikTheReaderAbilityGameState extends GameState<
unusedCards.unshift(westerosCard);
const newWesterosDeck = _.concat(unusedCards, discardedCards);
if (westerosDeck.length != newWesterosDeck.length) {
throw new Error(`Westeros deck ${deckId} is corrupt`);
throw new SnrError(this.entireGame, `Westeros deck ${deckId} is corrupt`);
}
this.game.westerosDecks[deckId] = newWesterosDeck;
// Broadcast manipulated deck for "CoK Westeros Phase Variant"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import IronBank, { IronBankSnapshot, SerializedIronBank } from "./IronBank";
import Player from "../Player";
import { ObjectiveCard } from "./static-data-structure/ObjectiveCard";
import { objectiveCards } from "./static-data-structure/objectiveCards";
import SnrError from "../../../utils/snrError";

export const MAX_WILDLING_STRENGTH = 12;
export const MAX_LOYALTY_TOKEN_COUNT = 20;
Expand Down Expand Up @@ -94,7 +95,7 @@ export default class Game {

get theIronBank(): IronBank {
if (this.ironBank == null) {
throw new Error("Iron Bank must be initalized when this is called!");
throw new SnrError(this.ingame.entireGame, "Iron Bank must be initalized when this is called!");
}

return this.ironBank;
Expand Down Expand Up @@ -128,12 +129,12 @@ export default class Game {
if (this.ingame.entireGame.isMotherOfDragons) {
if ((this.removedDragonStrengthToken == 0 && this.dragonStrengthTokens.length != 5)
|| (this.removedDragonStrengthToken != 0 && this.dragonStrengthTokens.length != 4)) {
throw new Error("Dragon strength tokens array is corrupted");
throw new SnrError(this.ingame.entireGame, "Dragon strength tokens array is corrupted");
}
} else if (this.ingame.entireGame.isDanceWithMotherOfDragons) {
if ((this.removedDragonStrengthToken == 0 && this.dragonStrengthTokens.length != 4)
|| (this.removedDragonStrengthToken != 0 && this.dragonStrengthTokens.length != 3)) {
throw new Error("Dragon strength tokens array is corrupted");
throw new SnrError(this.ingame.entireGame, "Dragon strength tokens array is corrupted");
}
}

Expand Down Expand Up @@ -162,7 +163,7 @@ export default class Game {
}
}

throw new Error("Error in calculating currentDragonStrength");
throw new SnrError(this.ingame.entireGame, "Error in calculating currentDragonStrength");
}

get loyaltyTokensOnBoardCount(): number {
Expand Down Expand Up @@ -202,7 +203,7 @@ export default class Game {
const nonVassalTrack = track.filter(h => !this.ingame.isVassalHouse(h));

if (nonVassalTrack.length == 0) {
throw new Error("There must be at least one non-vassal in the track");
throw new SnrError(this.ingame.entireGame, "There must be at least one non-vassal in the track");
}

return nonVassalTrack[0];
Expand Down Expand Up @@ -440,7 +441,7 @@ export default class Game {
getHouseCardById(id: string): HouseCard {
const allCards = this.getAllHouseCardsInGame();
if (!allCards.has(id)) {
throw new Error(`House card ${id} not found`);
throw new SnrError(this.ingame.entireGame, `House card ${id} not found`);
}
return allCards.get(id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UnitSlot from "../../../utils/unitSlot";
import _ from "lodash";
import getStaticWorld from "./static-data-structure/getStaticWorld";
import { port } from "./regionTypes";
import SnrError from "../../../utils/snrError";

export default class Region {
game: Game;
Expand Down Expand Up @@ -123,7 +124,7 @@ export default class Region {
// have the same allegiance.
const possibleController = this.units.values[0].allegiance;
if (!this.units.values.every(u => u.allegiance == possibleController)) {
throw new Error(
throw new SnrError(this.game.ingame.entireGame,
"getController was called on region \"" + this.id + "\" but multiple units of different allegiance are present in the region"
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function isTakeControlOfEnemyPortGameStateRequired(ingame: IngameGameStat
}

// We should never reach this line because we removed orphaned ships earlier.
throw new Error(`$Port with id '{portRegion.id}' contains orphaned ships which should have been removed before!`);
throw new Error(`Port with id '${portRegion.id}' contains orphaned ships which should have been removed before!`);
}

export interface TakeControlOfEnemyPortResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export default class MoveLoyaltyTokensGameState extends GameState<WesterosDeck4G
});
}

setChooseCancelLastMoveGameState(houseWhichMovedLoyaltyTokens: House): void {
setChooseCancelLastMoveGameState(_houseWhichMovedLoyaltyTokens: House): void {
if (!this.game.targaryen) {
throw new Error("Targaryen must be available here!");
}
Expand All @@ -162,7 +162,7 @@ export default class MoveLoyaltyTokensGameState extends GameState<WesterosDeck4G
this.getChoices(this.game.targaryen));
}

sendAcceptAllMovements(newValue: boolean) {
sendAcceptAllMovements(newValue: boolean): void {
this.entireGame.sendMessageToServer({
type: "change-accept-all-loyalty-token-movements",
newValue: newValue
Expand Down
8 changes: 8 additions & 0 deletions agot-bg-game-server/src/utils/snrError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import EntireGame from "../common/EntireGame";

export default class SnrError extends Error {
constructor(entireGame: EntireGame, msg?: string) {
msg = `Error in game ${entireGame.id}: ${msg}`;
super(msg);
}
}

0 comments on commit fd8a481

Please sign in to comment.