paper-dynasty-discord/exceptions.py
Cal Corum 4be6afb541 Add API timeout/retry logic and fix get_team_by_owner for PostgreSQL
- Add APITimeoutError exception and retry logic to db_get
- Add timeout handling to db_post, db_put, db_patch, db_delete
- Fix get_team_by_owner to prefer non-gauntlet team (PostgreSQL migration fix)
- Code formatting cleanup (black)
2026-01-31 15:52:14 -06:00

132 lines
2.3 KiB
Python

import logging
from typing import Literal
logger = logging.getLogger("discord_app")
def log_errors(func):
"""
This wrapper function will force all exceptions to be logged with execution and stack info.
"""
def wrap(*args, **kwargs):
try:
result = func(*args, **kwargs)
except Exception as e:
logger.error(func.__name__)
log_exception(e)
return result # type: ignore
return wrap
def log_exception(
e: Exception,
msg: str = "",
level: Literal["debug", "error", "info", "warn"] = "error",
):
if level == "debug":
logger.debug(msg, exc_info=True, stack_info=True)
elif level == "error":
logger.error(msg, exc_info=True, stack_info=True)
elif level == "info":
logger.info(msg, exc_info=True, stack_info=True)
else:
logger.warning(msg, exc_info=True, stack_info=True)
# Check if 'e' is an exception class or instance
if isinstance(e, Exception):
raise e # If 'e' is already an instance of an exception
else:
raise e(msg) # If 'e' is an exception class
class GameException(Exception):
pass
class LineupsMissingException(GameException):
pass
class CardLegalityException(GameException):
pass
class CardNotFoundException(GameException):
pass
class GameNotFoundException(GameException):
pass
class TeamNotFoundException(GameException):
pass
class PlayNotFoundException(GameException):
pass
class PlayerNotFoundException(GameException):
pass
class PlayInitException(GameException):
pass
class DatabaseError(GameException):
pass
class APITimeoutError(DatabaseError):
"""Raised when an API call times out after all retries."""
pass
class PositionNotFoundException(GameException):
pass
class NoPlayerResponseException(GameException):
pass
class MultipleHumanTeamsException(GameException):
pass
class NoHumanTeamsException(GameException):
pass
class GoogleSheetsException(GameException):
pass
class InvalidResultException(GameException):
pass
class ButtonOptionNotChosen(Exception):
pass
class MissingRoleException(GameException):
pass
class MissingRosterException(GameException):
pass
class LegalityCheckNotRequired(GameException):
pass
class InvalidResponder(GameException):
pass