From 16a9632e69a81ad2b6e8970a82360a8b80531582 Mon Sep 17 00:00:00 2001 From: Janis Date: Sun, 5 Apr 2026 13:22:13 +0200 Subject: [PATCH] fix(io): add error handling for missing piece in PgnExporter replay Replace unsafe fallback to Pawn with explicit exception on invariant violation. This ensures data corruption in GameContext.moves is detected immediately rather than producing silently incorrect PGN output. Co-Authored-By: Claude Sonnet 4.6 --- .../main/scala/de/nowchess/io/pgn/PgnExporter.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala b/modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala index e16c49a..326b43b 100644 --- a/modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala +++ b/modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala @@ -22,7 +22,15 @@ object PgnExporter extends GameContextExport: var ctx = GameContext.initial for move <- context.moves do val color = ctx.turn - val pieceType = ctx.board.pieceAt(move.from).map(_.pieceType).getOrElse(PieceType.Pawn) + val pieceType = ctx.board.pieceAt(move.from) + .map(_.pieceType) + .getOrElse { + val fromStr = move.from.toString + val boardStr = ctx.board.pieces.keys.map(_.toString).mkString(",") + throw new IllegalStateException( + s"Invariant violation: no piece at $fromStr during PGN export replay. Board squares: $boardStr" + ) + } val isCapture = ctx.board.pieceAt(move.to).isDefined || move.moveType == MoveType.EnPassant val castleSide = move.moveType match case MoveType.CastleKingside => Some("Kingside")