logoCheckmate
Program

Errors

The Chess program defines custom error codes for various failure scenarios. Understanding these errors is crucial for proper error handling in your integration.

Error Categories

Game State Errors

Errors related to invalid game states or transitions.

GameNotFound

  • Code: 6000
  • Description: The specified game account does not exist
  • Common Causes: Invalid game ID, game was never created

GameAlreadyStarted

  • Code: 6001
  • Description: Attempting to join a game that has already started
  • Common Causes: Second player trying to join after game began

GameNotStarted

  • Code: 6002
  • Description: Attempting game actions before both players have joined
  • Common Causes: Making moves before second player joins

GameFinished

  • Code: 6003
  • Description: Attempting actions on a completed game
  • Common Causes: Making moves after checkmate, resignation, or timeout

GameCancelled

  • Code: 6004
  • Description: Attempting actions on a cancelled game
  • Common Causes: Trying to join or play a cancelled game

Player Errors

Errors related to player authorization and turn management.

NotPlayerTurn

  • Code: 6010
  • Description: Player attempting to move when it's not their turn
  • Common Causes: White player moving on black's turn, or vice versa

NotGamePlayer

  • Code: 6011
  • Description: Account is not a player in this game
  • Common Causes: Unauthorized account trying to make moves

PlayerAlreadyJoined

  • Code: 6012
  • Description: Player trying to join a game they're already in
  • Common Causes: Duplicate join attempts

SamePlayerJoining

  • Code: 6013
  • Description: Same player trying to join as both white and black
  • Common Causes: Self-play attempts (if not allowed)

Chess Rule Errors

Errors related to chess move validation and rules.

InvalidMove

  • Code: 6020
  • Description: The attempted move violates chess rules
  • Common Causes: Illegal piece movement, moving into check

InvalidSquare

  • Code: 6021
  • Description: Invalid board coordinates
  • Common Causes: Coordinates outside 0-7 range

NoPieceAtSquare

  • Code: 6022
  • Description: Attempting to move from an empty square
  • Common Causes: Incorrect source square in move

WrongPieceColor

  • Code: 6023
  • Description: Attempting to move opponent's piece
  • Common Causes: Moving black piece on white's turn

KingInCheck

  • Code: 6024
  • Description: Move would leave or put king in check
  • Common Causes: Invalid moves that don't resolve check

InvalidCastling

  • Code: 6025
  • Description: Castling attempt violates castling rules
  • Common Causes: Castling through check, pieces moved previously

InvalidEnPassant

  • Code: 6026
  • Description: En passant capture attempt is invalid
  • Common Causes: No valid en passant target

InvalidPromotion

  • Code: 6027
  • Description: Pawn promotion is invalid or missing
  • Common Causes: Pawn reaching end rank without promotion piece

Time Control Errors

Errors related to time management and timeouts.

TimeExpired

  • Code: 6030
  • Description: Player's time has expired
  • Common Causes: Taking too long to make a move

InvalidTimeControl

  • Code: 6031
  • Description: Invalid time control settings
  • Common Causes: Negative time values, invalid increment

Economic Errors

Errors related to entry fees, prize pools, and payments.

InsufficientFunds

  • Code: 6040
  • Description: Player doesn't have enough SOL for entry fee
  • Common Causes: Low wallet balance

InvalidEntryFee

  • Code: 6041
  • Description: Entry fee amount is invalid
  • Common Causes: Negative or excessive entry fees

PrizeAlreadyClaimed

  • Code: 6042
  • Description: Prize has already been claimed
  • Common Causes: Duplicate claim attempts

NoPrizeTolaim

  • Code: 6043
  • Description: No prize available to claim
  • Common Causes: Claiming from lost or drawn games

Configuration Errors

Errors related to platform and integrator configuration.

InvalidAuthority

  • Code: 6050
  • Description: Account lacks required authority
  • Common Causes: Non-admin trying to modify config

InvalidIntegrator

  • Code: 6051
  • Description: Integrator account is invalid or not initialized
  • Common Causes: Using unregistered integrator

InvalidFeeRate

  • Code: 6052
  • Description: Fee rate exceeds maximum allowed
  • Common Causes: Setting fees above 100%

Draw System Errors

Errors related to draw offers and acceptance.

NoDrawOffer

  • Code: 6060
  • Description: No draw offer exists to accept/reject
  • Common Causes: Accepting non-existent draw offer

DrawOfferExists

  • Code: 6061
  • Description: Draw offer already exists
  • Common Causes: Multiple draw offers from same player

CannotOfferDraw

  • Code: 6062
  • Description: Player cannot offer draw in current state
  • Common Causes: Offering draw when not player's turn

Error Handling Best Practices

Client-Side Handling

try {
  await chessSDK.makeMove({
    gameId,
    move: { from: [0, 1], to: [0, 3] },
    player: playerKeypair
  });
} catch (error) {
  if (error.code === 6020) {
    console.error("Invalid move attempted");
    // Show user-friendly error message
  } else if (error.code === 6010) {
    console.error("Not your turn");
    // Update UI to reflect current turn
  } else {
    console.error("Unexpected error:", error);
  }
}

Error Recovery

const handleGameError = async (error: any, gameId: string) => {
  switch (error.code) {
    case 6030: // TimeExpired
      // Refresh game state and handle timeout
      await refreshGameState(gameId);
      break;
    
    case 6003: // GameFinished
      // Navigate to game results
      await showGameResults(gameId);
      break;
    
    case 6020: // InvalidMove
      // Reset move input and show valid moves
      resetMoveInput();
      highlightValidMoves();
      break;
    
    default:
      // Log unexpected errors
      console.error("Unhandled error:", error);
  }
};

Validation Before Transactions

const validateMoveBeforeSubmit = (gameState: GameState, move: ChessMove) => {
  // Check if it's player's turn
  if (gameState.currentTurn !== playerColor) {
    throw new Error("Not your turn");
  }
  
  // Check if game is in progress
  if (gameState.status !== "InProgress") {
    throw new Error("Game is not in progress");
  }
  
  // Validate move format
  if (!isValidMoveFormat(move)) {
    throw new Error("Invalid move format");
  }
  
  // Additional client-side validation...
};

Error Monitoring

const logError = (error: any, context: string) => {
  const errorData = {
    code: error.code,
    message: error.message,
    context,
    timestamp: new Date().toISOString(),
    gameId: currentGameId,
    player: playerPublicKey.toString()
  };
  
  // Send to monitoring service
  analytics.track("chess_game_error", errorData);
};

Common Error Scenarios

Scenario 1: Invalid Move Sequence

// User tries to move opponent's piece
try {
  await makeMove({ from: [0, 0], to: [0, 1] }); // Black rook on white's turn
} catch (error) {
  // Error 6023: WrongPieceColor
  showError("You can only move your own pieces");
}

Scenario 2: Time Management

// Player runs out of time
try {
  await makeMove({ from: [4, 1], to: [4, 3] });
} catch (error) {
  if (error.code === 6030) {
    // Error 6030: TimeExpired
    showGameResult("Time expired - you lose!");
  }
}

Scenario 3: Game State Conflicts

// Trying to join a full game
try {
  await joinGame({ gameId, player: playerKeypair });
} catch (error) {
  if (error.code === 6001) {
    // Error 6001: GameAlreadyStarted
    showError("This game has already started");
    navigateToGameList();
  }
}

Testing Error Conditions

Unit Tests

describe("Chess Program Errors", () => {
  it("should throw InvalidMove for illegal moves", async () => {
    await expect(
      program.methods.makeMove(illegalMove)
        .accounts({ gameAccount })
        .rpc()
    ).to.be.rejectedWith(/6020/);
  });
  
  it("should throw NotPlayerTurn for wrong turn", async () => {
    await expect(
      program.methods.makeMove(validMove)
        .accounts({ gameAccount })
        .signers([wrongPlayer])
        .rpc()
    ).to.be.rejectedWith(/6010/);
  });
});

Integration Tests

const testErrorScenarios = async () => {
  // Test timeout scenario
  const gameWithTimeout = await createGameWithShortTime();
  await sleep(timeLimit + 1000);
  
  try {
    await makeMove(gameWithTimeout, validMove);
    assert.fail("Should have thrown TimeExpired");
  } catch (error) {
    assert.equal(error.code, 6030);
  }
};