mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-18 16:40:12 +01:00
Began work on overhauling the deck_builder
This commit is contained in:
parent
e0dd09adee
commit
319f7848d3
10 changed files with 2589 additions and 761 deletions
676
exceptions.py
676
exceptions.py
|
|
@ -1,64 +1,237 @@
|
|||
"""Custom exceptions for MTG Python Deckbuilder setup operations."""
|
||||
"""Custom exceptions for the MTG Python Deckbuilder application."""
|
||||
|
||||
class MTGSetupError(Exception):
|
||||
"""Base exception class for MTG setup-related errors."""
|
||||
pass
|
||||
class DeckBuilderError(Exception):
|
||||
"""Base exception class for deck builder errors.
|
||||
|
||||
Attributes:
|
||||
code (str): Error code for identifying the error type
|
||||
message (str): Descriptive error message
|
||||
details (dict): Additional error context and details
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, code: str = "DECK_ERR", details: dict | None = None):
|
||||
"""Initialize the base deck builder error.
|
||||
|
||||
Args:
|
||||
message: Human-readable error description
|
||||
code: Error code for identification and handling
|
||||
details: Additional context about the error
|
||||
"""
|
||||
self.code = code
|
||||
self.message = message
|
||||
self.details = details or {}
|
||||
super().__init__(self.message)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Format the error message with code and details."""
|
||||
error_msg = f"[{self.code}] {self.message}"
|
||||
if self.details:
|
||||
error_msg += f"\nDetails: {self.details}"
|
||||
return error_msg
|
||||
|
||||
class MTGSetupError(DeckBuilderError):
|
||||
"""Base exception class for MTG setup-related errors.
|
||||
|
||||
This exception serves as the base for all setup-related errors in the deck builder,
|
||||
including file operations, data processing, and validation during setup.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, code: str = "SETUP_ERR", details: dict | None = None):
|
||||
"""Initialize the base setup error.
|
||||
|
||||
Args:
|
||||
message: Human-readable error description
|
||||
code: Error code for identification and handling
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code=code, details=details)
|
||||
|
||||
class CSVFileNotFoundError(MTGSetupError):
|
||||
"""Exception raised when a required CSV file is not found.
|
||||
|
||||
This exception is raised when attempting to access or process a CSV file
|
||||
that does not exist in the expected location.
|
||||
|
||||
Args:
|
||||
message: Explanation of the error
|
||||
filename: Name of the missing CSV file
|
||||
"""
|
||||
def __init__(self, message: str, filename: str) -> None:
|
||||
self.filename = filename
|
||||
super().__init__(f"{message}: {filename}")
|
||||
|
||||
def __init__(self, filename: str, details: dict | None = None):
|
||||
"""Initialize CSV file not found error.
|
||||
|
||||
Args:
|
||||
filename: Name of the missing CSV file
|
||||
details: Additional context about the missing file
|
||||
"""
|
||||
message = f"Required CSV file not found: '{filename}'"
|
||||
super().__init__(message, code="CSV_MISSING", details=details)
|
||||
|
||||
class MTGJSONDownloadError(MTGSetupError):
|
||||
"""Exception raised when downloading data from MTGJSON fails.
|
||||
|
||||
This exception is raised when there are issues downloading card data
|
||||
from the MTGJSON API, such as network errors or API failures.
|
||||
|
||||
Args:
|
||||
message: Explanation of the error
|
||||
url: The URL that failed to download
|
||||
status_code: HTTP status code if available
|
||||
"""
|
||||
def __init__(self, message: str, url: str, status_code: int = None) -> None:
|
||||
self.url = url
|
||||
self.status_code = status_code
|
||||
|
||||
def __init__(self, url: str, status_code: int | None = None, details: dict | None = None):
|
||||
"""Initialize MTGJSON download error.
|
||||
|
||||
Args:
|
||||
url: The URL that failed to download
|
||||
status_code: HTTP status code if available
|
||||
details: Additional context about the download failure
|
||||
"""
|
||||
status_info = f" (Status: {status_code})" if status_code else ""
|
||||
super().__init__(f"{message}: {url}{status_info}")
|
||||
message = f"Failed to download from MTGJSON: {url}{status_info}"
|
||||
super().__init__(message, code="MTGJSON_ERR", details=details)
|
||||
|
||||
class DataFrameProcessingError(MTGSetupError):
|
||||
"""Exception raised when DataFrame operations fail during setup.
|
||||
# Input Handler Exceptions
|
||||
class EmptyInputError(DeckBuilderError):
|
||||
"""Raised when text input validation fails due to empty or whitespace-only input.
|
||||
|
||||
This exception is raised when there are issues processing card data
|
||||
in pandas DataFrames, such as filtering, sorting, or transformation errors.
|
||||
|
||||
Args:
|
||||
message: Explanation of the error
|
||||
operation: The DataFrame operation that failed (e.g., 'color_filtering', 'commander_processing')
|
||||
details: Additional error details
|
||||
|
||||
Examples:
|
||||
>>> raise DataFrameProcessingError(
|
||||
... "Invalid color identity",
|
||||
... "color_filtering",
|
||||
... "Color 'P' is not a valid MTG color"
|
||||
... )
|
||||
This exception is used by the validate_text method when checking user input.
|
||||
"""
|
||||
def __init__(self, message: str, operation: str, details: str = None) -> None:
|
||||
self.operation = operation
|
||||
self.details = details
|
||||
error_info = f" - {details}" if details else ""
|
||||
super().__init__(f"{message} during {operation}{error_info}")
|
||||
|
||||
def __init__(self, field_name: str = "input", details: dict | None = None):
|
||||
"""Initialize empty input error.
|
||||
|
||||
Args:
|
||||
field_name: Name of the input field that was empty
|
||||
details: Additional context about the validation failure
|
||||
"""
|
||||
message = f"Empty or whitespace-only {field_name} is not allowed"
|
||||
super().__init__(message, code="EMPTY_INPUT", details=details)
|
||||
|
||||
class InvalidNumberError(DeckBuilderError):
|
||||
"""Raised when number input validation fails.
|
||||
|
||||
This exception is used by the validate_number method when checking numeric input.
|
||||
"""
|
||||
|
||||
def __init__(self, value: str, details: dict | None = None):
|
||||
"""Initialize invalid number error.
|
||||
|
||||
Args:
|
||||
value: The invalid input value
|
||||
details: Additional context about the validation failure
|
||||
"""
|
||||
message = f"Invalid number format: '{value}'"
|
||||
super().__init__(message, code="INVALID_NUM", details=details)
|
||||
|
||||
class InvalidQuestionTypeError(DeckBuilderError):
|
||||
"""Raised when an unsupported question type is used in the questionnaire method.
|
||||
|
||||
This exception is raised when the questionnaire method receives an unknown question type.
|
||||
"""
|
||||
|
||||
def __init__(self, question_type: str, details: dict | None = None):
|
||||
"""Initialize invalid question type error.
|
||||
|
||||
Args:
|
||||
question_type: The unsupported question type
|
||||
details: Additional context about the error
|
||||
"""
|
||||
message = f"Unsupported question type: '{question_type}'"
|
||||
super().__init__(message, code="INVALID_QTYPE", details=details)
|
||||
|
||||
class MaxAttemptsError(DeckBuilderError):
|
||||
"""Raised when maximum input attempts are exceeded.
|
||||
|
||||
This exception is used when user input validation fails multiple times.
|
||||
"""
|
||||
|
||||
def __init__(self, max_attempts: int, input_type: str = "input", details: dict | None = None):
|
||||
"""Initialize maximum attempts error.
|
||||
|
||||
Args:
|
||||
max_attempts: Maximum number of attempts allowed
|
||||
input_type: Type of input that failed validation
|
||||
details: Additional context about the attempts
|
||||
"""
|
||||
message = f"Maximum {input_type} attempts ({max_attempts}) exceeded"
|
||||
super().__init__(message, code="MAX_ATTEMPTS", details=details)
|
||||
|
||||
# CSV Exceptions
|
||||
class CSVError(DeckBuilderError):
|
||||
"""Base exception class for CSV-related errors.
|
||||
|
||||
This exception serves as the base for all CSV-related errors in the deck builder,
|
||||
including file reading, processing, validation, and timeout issues.
|
||||
|
||||
Attributes:
|
||||
code (str): Error code for identifying the error type
|
||||
message (str): Descriptive error message
|
||||
details (dict): Additional error context and details
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, code: str = "CSV_ERR", details: dict | None = None):
|
||||
"""Initialize the base CSV error.
|
||||
|
||||
Args:
|
||||
message: Human-readable error description
|
||||
code: Error code for identification and handling
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code=code, details=details)
|
||||
|
||||
class CSVReadError(CSVError):
|
||||
"""Raised when there are issues reading CSV files.
|
||||
|
||||
This exception is used when CSV files cannot be opened, read, or parsed.
|
||||
"""
|
||||
|
||||
def __init__(self, filename: str, details: dict | None = None):
|
||||
"""Initialize CSV read error.
|
||||
|
||||
Args:
|
||||
filename: Name of the CSV file that failed to read
|
||||
details: Additional context about the read failure
|
||||
"""
|
||||
message = f"Failed to read CSV file: '{filename}'"
|
||||
super().__init__(message, code="CSV_READ", details=details)
|
||||
|
||||
class CSVProcessingError(CSVError):
|
||||
"""Base class for CSV and DataFrame processing errors.
|
||||
|
||||
This exception is used when operations fail during data processing,
|
||||
including batch operations and transformations.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, operation_context: dict | None = None, details: dict | None = None):
|
||||
"""Initialize processing error with context.
|
||||
|
||||
Args:
|
||||
message: Descriptive error message
|
||||
operation_context: Details about the failed operation
|
||||
details: Additional error context
|
||||
"""
|
||||
if operation_context:
|
||||
details = details or {}
|
||||
details['operation_context'] = operation_context
|
||||
super().__init__(message, code="CSV_PROC", details=details)
|
||||
|
||||
class DataFrameProcessingError(CSVProcessingError):
|
||||
"""Raised when DataFrame batch operations fail.
|
||||
|
||||
This exception provides detailed context about batch processing failures
|
||||
including operation state and progress information.
|
||||
"""
|
||||
|
||||
def __init__(self, operation: str, batch_state: dict, processed_count: int, total_count: int, details: dict | None = None):
|
||||
"""Initialize DataFrame processing error.
|
||||
|
||||
Args:
|
||||
operation: Name of the operation that failed
|
||||
batch_state: Current state of batch processing
|
||||
processed_count: Number of items processed
|
||||
total_count: Total number of items to process
|
||||
details: Additional error context
|
||||
"""
|
||||
message = f"DataFrame batch operation '{operation}' failed after processing {processed_count}/{total_count} items"
|
||||
operation_context = {
|
||||
'operation': operation,
|
||||
'batch_state': batch_state,
|
||||
'processed_count': processed_count,
|
||||
'total_count': total_count
|
||||
}
|
||||
super().__init__(message, operation_context, details)
|
||||
|
||||
class ColorFilterError(MTGSetupError):
|
||||
"""Exception raised when color-specific filtering operations fail.
|
||||
|
|
@ -84,113 +257,330 @@ class ColorFilterError(MTGSetupError):
|
|||
error_info = f" - {details}" if details else ""
|
||||
super().__init__(f"{message} for color '{color}'{error_info}")
|
||||
|
||||
|
||||
class CommanderValidationError(MTGSetupError):
|
||||
"""Exception raised when commander validation fails.
|
||||
class CSVValidationError(CSVError):
|
||||
"""Base class for CSV and DataFrame validation errors.
|
||||
|
||||
This exception is raised when there are issues validating commander cards,
|
||||
such as non-legendary creatures, color identity mismatches, or banned cards.
|
||||
|
||||
Args:
|
||||
message: Explanation of the error
|
||||
validation_type: Type of validation that failed (e.g., 'legendary_check', 'color_identity', 'banned_set')
|
||||
details: Additional error details
|
||||
|
||||
Examples:
|
||||
>>> raise CommanderValidationError(
|
||||
... "Card must be legendary",
|
||||
... "legendary_check",
|
||||
... "Lightning Bolt is not a legendary creature"
|
||||
... )
|
||||
|
||||
>>> raise CommanderValidationError(
|
||||
... "Commander color identity mismatch",
|
||||
... "color_identity",
|
||||
... "Omnath, Locus of Creation cannot be used in Golgari deck"
|
||||
... )
|
||||
|
||||
>>> raise CommanderValidationError(
|
||||
... "Commander banned in format",
|
||||
... "banned_set",
|
||||
... "Golos, Tireless Pilgrim is banned in Commander"
|
||||
... )
|
||||
This exception is used when data fails validation checks, including field validation,
|
||||
data type validation, and data consistency validation.
|
||||
"""
|
||||
def __init__(self, message: str, validation_type: str, details: str = None) -> None:
|
||||
self.validation_type = validation_type
|
||||
self.details = details
|
||||
error_info = f" - {details}" if details else ""
|
||||
super().__init__(f"{message} [{validation_type}]{error_info}")
|
||||
|
||||
|
||||
class InputValidationError(MTGSetupError):
|
||||
"""Exception raised when input validation fails.
|
||||
|
||||
This exception is raised when there are issues validating user input,
|
||||
such as invalid text formats, number ranges, or confirmation responses.
|
||||
|
||||
Args:
|
||||
message: Explanation of the error
|
||||
input_type: Type of input validation that failed (e.g., 'text', 'number', 'confirm')
|
||||
details: Additional error details
|
||||
|
||||
Examples:
|
||||
>>> raise InputValidationError(
|
||||
... "Invalid number input",
|
||||
... "number",
|
||||
... "Value must be between 1 and 100"
|
||||
... )
|
||||
def __init__(self, message: str, validation_context: dict | None = None, details: dict | None = None):
|
||||
"""Initialize validation error with context.
|
||||
|
||||
>>> raise InputValidationError(
|
||||
... "Invalid confirmation response",
|
||||
... "confirm",
|
||||
... "Please enter 'y' or 'n'"
|
||||
... )
|
||||
|
||||
>>> raise InputValidationError(
|
||||
... "Invalid text format",
|
||||
... "text",
|
||||
... "Input contains invalid characters"
|
||||
... )
|
||||
Args:
|
||||
message: Descriptive error message
|
||||
validation_context: Specific validation failure details
|
||||
details: Additional error context
|
||||
"""
|
||||
if validation_context:
|
||||
details = details or {}
|
||||
details['validation_context'] = validation_context
|
||||
super().__init__(message, code="CSV_VALID", details=details)
|
||||
|
||||
class DataFrameValidationError(CSVValidationError):
|
||||
"""Raised when DataFrame validation fails.
|
||||
|
||||
This exception provides detailed context about validation failures including
|
||||
rule violations, invalid values, and data type mismatches.
|
||||
"""
|
||||
def __init__(self, message: str, input_type: str, details: str = None) -> None:
|
||||
self.input_type = input_type
|
||||
self.details = details
|
||||
error_info = f" - {details}" if details else ""
|
||||
super().__init__(f"{message} [{input_type}]{error_info}")
|
||||
|
||||
|
||||
class PriceCheckError(MTGSetupError):
|
||||
"""Exception raised when price checking operations fail.
|
||||
|
||||
This exception is raised when there are issues retrieving or processing
|
||||
card prices, such as API failures, invalid responses, or parsing errors.
|
||||
|
||||
Args:
|
||||
message: Explanation of the error
|
||||
card_name: Name of the card that caused the error
|
||||
details: Additional error details
|
||||
|
||||
Examples:
|
||||
>>> raise PriceCheckError(
|
||||
... "Failed to retrieve price",
|
||||
... "Black Lotus",
|
||||
... "API request timeout"
|
||||
... )
|
||||
def __init__(self, field: str, validation_rules: dict, invalid_data: dict | None = None, details: dict | None = None):
|
||||
"""Initialize DataFrame validation error.
|
||||
|
||||
>>> raise PriceCheckError(
|
||||
... "Invalid price data format",
|
||||
... "Lightning Bolt",
|
||||
... "Unexpected response structure"
|
||||
... )
|
||||
|
||||
>>> raise PriceCheckError(
|
||||
... "Price data unavailable",
|
||||
... "Underground Sea",
|
||||
... "No price information found"
|
||||
... )
|
||||
Args:
|
||||
field: Name of the field that failed validation
|
||||
validation_rules: Rules that were violated
|
||||
invalid_data: The invalid data that caused the failure
|
||||
details: Additional error context
|
||||
"""
|
||||
message = f"DataFrame validation failed for field '{field}'"
|
||||
validation_context = {
|
||||
'field': field,
|
||||
'rules': validation_rules,
|
||||
'invalid_data': invalid_data or {}
|
||||
}
|
||||
super().__init__(message, validation_context, details)
|
||||
|
||||
class EmptyDataFrameError(CSVError):
|
||||
"""Raised when a DataFrame is unexpectedly empty.
|
||||
|
||||
This exception is used when a DataFrame operation requires non-empty data
|
||||
but receives an empty DataFrame.
|
||||
"""
|
||||
def __init__(self, message: str, card_name: str, details: str = None) -> None:
|
||||
self.card_name = card_name
|
||||
self.details = details
|
||||
error_info = f" - {details}" if details else ""
|
||||
super().__init__(f"{message} for card '{card_name}'{error_info}")
|
||||
|
||||
def __init__(self, operation: str, details: dict | None = None):
|
||||
"""Initialize empty DataFrame error.
|
||||
|
||||
Args:
|
||||
operation: Name of the operation that requires non-empty data
|
||||
details: Additional context about the empty DataFrame
|
||||
"""
|
||||
message = f"Empty DataFrame encountered during: '{operation}'"
|
||||
super().__init__(message, code="CSV_EMPTY", details=details)
|
||||
|
||||
class CSVTimeoutError(CSVError):
|
||||
"""Base class for CSV and DataFrame timeout errors.
|
||||
|
||||
This exception is used when operations exceed their timeout thresholds.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, timeout_context: dict | None = None, details: dict | None = None):
|
||||
"""Initialize timeout error with context.
|
||||
|
||||
Args:
|
||||
message: Descriptive error message
|
||||
timeout_context: Details about the timeout
|
||||
details: Additional error context
|
||||
"""
|
||||
if timeout_context:
|
||||
details = details or {}
|
||||
details['timeout_context'] = timeout_context
|
||||
super().__init__(message, code="CSV_TIMEOUT", details=details)
|
||||
|
||||
class DataFrameTimeoutError(CSVTimeoutError):
|
||||
"""Raised when DataFrame operations timeout.
|
||||
|
||||
This exception provides detailed context about operation timeouts
|
||||
including operation type and duration information.
|
||||
"""
|
||||
|
||||
def __init__(self, operation: str, timeout: float, elapsed: float, operation_state: dict | None = None, details: dict | None = None):
|
||||
"""Initialize DataFrame timeout error.
|
||||
|
||||
Args:
|
||||
operation: Name of the operation that timed out
|
||||
timeout: Timeout threshold in seconds
|
||||
elapsed: Actual time elapsed in seconds
|
||||
operation_state: State of the operation when timeout occurred
|
||||
details: Additional error context
|
||||
"""
|
||||
message = f"DataFrame operation '{operation}' timed out after {elapsed:.1f}s (threshold: {timeout}s)"
|
||||
timeout_context = {
|
||||
'operation': operation,
|
||||
'timeout_threshold': timeout,
|
||||
'elapsed_time': elapsed,
|
||||
'operation_state': operation_state or {}
|
||||
}
|
||||
super().__init__(message, timeout_context, details)
|
||||
|
||||
# For PriceCheck/Scrython functions
|
||||
class PriceError(DeckBuilderError):
|
||||
"""Base exception class for price-related errors.
|
||||
|
||||
This exception serves as the base for all price-related errors in the deck builder,
|
||||
including API issues, validation errors, and price limit violations.
|
||||
|
||||
Attributes:
|
||||
code (str): Error code for identifying the error type
|
||||
message (str): Descriptive error message
|
||||
details (dict): Additional error context and details
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, code: str = "PRICE_ERR", details: dict | None = None):
|
||||
"""Initialize the base price error.
|
||||
|
||||
Args:
|
||||
message: Human-readable error description
|
||||
code: Error code for identification and handling
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code=code, details=details)
|
||||
|
||||
class PriceAPIError(PriceError):
|
||||
"""Raised when there are issues with the Scryfall API price lookup.
|
||||
|
||||
This exception is used when the price API request fails, returns invalid data,
|
||||
or encounters other API-related issues.
|
||||
"""
|
||||
|
||||
def __init__(self, card_name: str, details: dict | None = None):
|
||||
"""Initialize price API error.
|
||||
|
||||
Args:
|
||||
card_name: Name of the card that failed price lookup
|
||||
details: Additional context about the API failure
|
||||
"""
|
||||
message = f"Failed to fetch price data for '{card_name}' from Scryfall API"
|
||||
super().__init__(message, code="PRICE_API", details=details)
|
||||
|
||||
class PriceLimitError(PriceError):
|
||||
"""Raised when a card or deck price exceeds the specified limit.
|
||||
|
||||
This exception is used when price thresholds are violated during deck building.
|
||||
"""
|
||||
|
||||
def __init__(self, card_name: str, price: float, limit: float, details: dict | None = None):
|
||||
"""Initialize price limit error.
|
||||
|
||||
Args:
|
||||
card_name: Name of the card exceeding the price limit
|
||||
price: Actual price of the card
|
||||
limit: Maximum allowed price
|
||||
details: Additional context about the price limit violation
|
||||
"""
|
||||
message = f"Price of '{card_name}' (${price:.2f}) exceeds limit of ${limit:.2f}"
|
||||
super().__init__(message, code="PRICE_LIMIT", details=details)
|
||||
|
||||
class PriceTimeoutError(PriceError):
|
||||
"""Raised when a price lookup request times out.
|
||||
|
||||
This exception is used when the Scryfall API request exceeds the timeout threshold.
|
||||
"""
|
||||
|
||||
def __init__(self, card_name: str, timeout: float, details: dict | None = None):
|
||||
"""Initialize price timeout error.
|
||||
|
||||
Args:
|
||||
card_name: Name of the card that timed out
|
||||
timeout: Timeout threshold in seconds
|
||||
details: Additional context about the timeout
|
||||
"""
|
||||
message = f"Price lookup for '{card_name}' timed out after {timeout} seconds"
|
||||
super().__init__(message, code="PRICE_TIMEOUT", details=details)
|
||||
|
||||
class PriceValidationError(PriceError):
|
||||
"""Raised when price data fails validation.
|
||||
|
||||
This exception is used when received price data is invalid, malformed,
|
||||
or cannot be properly parsed.
|
||||
"""
|
||||
|
||||
def __init__(self, card_name: str, price_data: str, details: dict | None = None):
|
||||
"""Initialize price validation error.
|
||||
|
||||
Args:
|
||||
card_name: Name of the card with invalid price data
|
||||
price_data: The invalid price data received
|
||||
details: Additional context about the validation failure
|
||||
"""
|
||||
message = f"Invalid price data for '{card_name}': {price_data}"
|
||||
super().__init__(message, code="PRICE_INVALID", details=details)
|
||||
|
||||
# Commander Exceptions
|
||||
class CommanderLoadError(DeckBuilderError):
|
||||
"""Raised when there are issues loading commander data from CSV.
|
||||
|
||||
This exception is used when the commander CSV file cannot be loaded,
|
||||
is missing required columns, or contains invalid data.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander load error.
|
||||
|
||||
Args:
|
||||
message: Description of the loading failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_LOAD", details=details)
|
||||
|
||||
class CommanderSelectionError(DeckBuilderError):
|
||||
"""Raised when there are issues with the commander selection process.
|
||||
|
||||
This exception is used when the commander selection process fails,
|
||||
such as no matches found or ambiguous matches.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander selection error.
|
||||
|
||||
Args:
|
||||
message: Description of the selection failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_SELECT", details=details)
|
||||
|
||||
class CommanderValidationError(DeckBuilderError):
|
||||
"""Raised when commander data fails validation.
|
||||
|
||||
This exception is used when the selected commander's data is invalid,
|
||||
missing required fields, or contains inconsistent information.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander validation error.
|
||||
|
||||
Args:
|
||||
message: Description of the validation failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_VALID", details=details)
|
||||
|
||||
class CommanderTypeError(CommanderValidationError):
|
||||
"""Raised when commander type validation fails.
|
||||
|
||||
This exception is used when a commander fails the legendary creature requirement
|
||||
or has an invalid creature type.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander type error.
|
||||
|
||||
Args:
|
||||
message: Description of the type validation failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_TYPE_ERR", details=details)
|
||||
|
||||
class CommanderStatsError(CommanderValidationError):
|
||||
"""Raised when commander stats validation fails.
|
||||
|
||||
This exception is used when a commander's power, toughness, or mana value
|
||||
fails validation requirements.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander stats error.
|
||||
|
||||
Args:
|
||||
message: Description of the stats validation failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_STATS_ERR", details=details)
|
||||
|
||||
class CommanderColorError(CommanderValidationError):
|
||||
"""Raised when commander color identity validation fails.
|
||||
|
||||
This exception is used when a commander's color identity is invalid
|
||||
or incompatible with deck requirements.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander color error.
|
||||
|
||||
Args:
|
||||
message: Description of the color validation failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_COLOR_ERR", details=details)
|
||||
|
||||
class CommanderTagError(CommanderValidationError):
|
||||
"""Raised when commander theme tag validation fails.
|
||||
|
||||
This exception is used when a commander's theme tags are invalid
|
||||
or incompatible with deck requirements.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander tag error.
|
||||
|
||||
Args:
|
||||
message: Description of the tag validation failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_TAG_ERR", details=details)
|
||||
|
||||
class CommanderThemeError(CommanderValidationError):
|
||||
"""Raised when commander theme validation fails.
|
||||
|
||||
This exception is used when a commander's themes are invalid
|
||||
or incompatible with deck requirements.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str, details: dict | None = None):
|
||||
"""Initialize commander theme error.
|
||||
|
||||
Args:
|
||||
message: Description of the theme validation failure
|
||||
details: Additional context about the error
|
||||
"""
|
||||
super().__init__(message, code="CMD_THEME_ERR", details=details)
|
||||
Loading…
Add table
Add a link
Reference in a new issue