Documentation Index
Fetch the complete documentation index at: https://mintlify.com/TracingInsights/tif1/llms.txt
Use this file to discover all available pages before exploring further.
The tif1.exceptions module defines a comprehensive exception hierarchy for error handling throughout the library. All exceptions inherit from the base TIF1Error class and support structured context information.
Exception Hierarchy
TIF1Error
├── DataNotFoundError
│ ├── DriverNotFoundError
│ └── LapNotFoundError
├── NetworkError
├── InvalidDataError
├── CacheError
└── SessionNotLoadedError
Base Exception
TIF1Error
class TIF1Error(Exception):
"""Base exception for tif1."""
def __init__(self, message: str, **context: Any) -> None:
...
Base exception class for all tif1 errors. Stores both a message and arbitrary context information for debugging.
Attributes:
message: str - Human-readable error message
context: dict[str, Any] - Additional context information passed as kwargs
When Raised:
Not raised directly; serves as base class for all other tif1 exceptions.
Example:
try:
session.load()
except TIF1Error as e:
print(f"Error: {e.message}")
print(f"Context: {e.context}")
Data Errors
DataNotFoundError
class DataNotFoundError(TIF1Error):
"""Raised when requested data is not available."""
def __init__(
self,
year: int | None = None,
event: str | None = None,
session: str | None = None,
**context: Any,
) -> None:
...
Raised when requested F1 data is not available from the data source.
Parameters:
year: int | None - Year of the event
event: str | None - Event name or identifier
session: str | None - Session type
**context - Additional context information
Context Attributes:
- Stores
year, event, session in context dict
- Plus any additional kwargs passed
When Raised:
- Session data not available for the specified year/event/session combination
- Event not found in the schedule
- Session type not available for the event
- Data source returns 404 or indicates data doesn’t exist
Example:
import tif1
from tif1.exceptions import DataNotFoundError
try:
session = tif1.get_session(2030, "NonExistent", "Race")
session.load()
except DataNotFoundError as e:
print(f"Could not find data: {e.message}")
print(f"Year: {e.context.get('year')}")
print(f"Event: {e.context.get('event')}")
DriverNotFoundError
class DriverNotFoundError(DataNotFoundError):
"""Raised when driver is not found in session."""
def __init__(self, driver: str, **context: Any) -> None:
...
Raised when attempting to access a driver that doesn’t exist in the session.
Parameters:
driver: str - Driver identifier that was not found
**context - Additional context information
Context Attributes:
driver - The driver identifier that was searched for
- Plus any additional kwargs passed
When Raised:
- Calling
session.get_driver() with an invalid driver code
- Accessing
session.laps.pick_driver() with non-existent driver
- Driver not participating in the session
- Invalid driver number or 3-letter code
Example:
import tif1
from tif1.exceptions import DriverNotFoundError
session = tif1.get_session(2024, "Monaco", "Race")
session.load()
try:
driver = session.get_driver("XXX") # Invalid driver code
except DriverNotFoundError as e:
print(f"Error: {e.message}")
print(f"Driver: {e.context['driver']}")
LapNotFoundError
class LapNotFoundError(DataNotFoundError):
"""Raised when lap is not found."""
def __init__(
self,
lap_number: int | None = None,
driver: str | None = None,
**context: Any,
) -> None:
...
Raised when attempting to access a lap that doesn’t exist.
Parameters:
lap_number: int | None - Lap number that was not found
driver: str | None - Driver for whom the lap was searched
**context - Additional context information
Context Attributes:
lap_number - The lap number searched for
driver - The driver identifier
- Plus any additional kwargs passed
When Raised:
- Requesting a lap number that doesn’t exist for a driver
- Accessing out-of-range lap indices
- Driver didn’t complete the requested lap (DNF, DNS)
- Lap data not available or was deleted
Example:
import tif1
from tif1.exceptions import LapNotFoundError
session = tif1.get_session(2024, "Monaco", "Race")
session.load()
try:
lap = session.laps.pick_driver("VER").pick_lap(999) # Non-existent lap
except LapNotFoundError as e:
print(f"Error: {e.message}")
print(f"Lap: {e.context.get('lap_number')}")
print(f"Driver: {e.context.get('driver')}")
Network Errors
NetworkError
class NetworkError(TIF1Error):
"""Raised when network request fails."""
def __init__(
self,
url: str | None = None,
status_code: int | None = None,
**context: Any,
) -> None:
...
Raised when HTTP requests to data sources fail.
Parameters:
url: str | None - URL that failed
status_code: int | None - HTTP status code received
**context - Additional context information
Context Attributes:
url - The URL that was requested
status_code - HTTP status code (e.g., 500, 503)
- Plus any additional kwargs passed
When Raised:
- HTTP request timeout
- Server returns 5xx error
- Connection failure
- CDN unavailable
- Network connectivity issues
- Rate limiting (429)
- Circuit breaker open after repeated failures
Example:
import tif1
from tif1.exceptions import NetworkError
try:
session = tif1.get_session(2024, "Monaco", "Race")
session.load()
except NetworkError as e:
print(f"Network error: {e.message}")
print(f"URL: {e.context.get('url')}")
print(f"Status: {e.context.get('status_code')}")
Data Validation Errors
InvalidDataError
class InvalidDataError(TIF1Error):
"""Raised when fetched data is invalid or corrupted."""
def __init__(self, reason: str | None = None, **context: Any) -> None:
...
Raised when data from sources is malformed, corrupted, or doesn’t match expected schema.
Parameters:
reason: str | None - Description of what is invalid
**context - Additional context information
Context Attributes:
reason - Why the data is invalid
- Plus any additional kwargs passed
When Raised:
- JSON parsing fails
- Data doesn’t match expected schema
- Required fields missing from response
- Data type mismatches
- Corrupted cache entries
- Invalid data format
Example:
import tif1
from tif1.exceptions import InvalidDataError
try:
session = tif1.get_session(2024, "Monaco", "Race")
session.load()
except InvalidDataError as e:
print(f"Invalid data: {e.message}")
print(f"Reason: {e.context.get('reason')}")
Cache Errors
CacheError
class CacheError(TIF1Error):
"""Raised when cache operations fail."""
Raised when SQLite cache operations encounter errors.
When Raised:
- Cannot create cache directory
- SQLite database corruption
- Insufficient disk space for cache
- Cache database locked
- Permission errors on cache files
- Cache write failures
Example:
import tif1
from tif1.exceptions import CacheError
try:
session = tif1.get_session(2024, "Monaco", "Race")
session.load()
except CacheError as e:
print(f"Cache error: {e.message}")
print(f"Context: {e.context}")
Session State Errors
SessionNotLoadedError
class SessionNotLoadedError(TIF1Error):
"""Raised when accessing session data before loading."""
def __init__(self, attribute: str | None = None) -> None:
...
Raised when attempting to access session data before calling session.load().
Parameters:
attribute: str | None - The attribute that was accessed
Context Attributes:
attribute - Name of the attribute that requires loading
When Raised:
- Accessing
session.laps before load()
- Accessing
session.results before load()
- Accessing
session.weather before load(laps=True, weather=True)
- Accessing any data property that requires loaded data
Example:
import tif1
from tif1.exceptions import SessionNotLoadedError
session = tif1.get_session(2024, "Monaco", "Race")
try:
laps = session.laps # Accessing before load()
except SessionNotLoadedError as e:
print(f"Error: {e.message}")
print(f"Attribute: {e.context.get('attribute')}")
# Solution: call session.load() first
session.load()
laps = session.laps # Now works
Error Handling Best Practices
Catch Specific Exceptions
import tif1
from tif1.exceptions import (
DataNotFoundError,
NetworkError,
SessionNotLoadedError,
TIF1Error,
)
def load_session_safely(year: int, event: str, session_type: str):
try:
session = tif1.get_session(year, event, session_type)
session.load()
return session
except SessionNotLoadedError:
print("Session not loaded - this shouldn't happen here")
except DataNotFoundError as e:
print(f"Data not available: {e.context}")
return None
except NetworkError as e:
print(f"Network issue, retry later: {e.context.get('status_code')}")
return None
except TIF1Error as e:
print(f"Other tif1 error: {e.message}")
return None
Access Error Context
from tif1.exceptions import DriverNotFoundError
try:
driver = session.get_driver("XXX")
except DriverNotFoundError as e:
# Access structured context
driver_code = e.context["driver"]
print(f"Driver '{driver_code}' not found")
# Available drivers for suggestion
available = [d.abbreviation for d in session.drivers]
print(f"Available drivers: {', '.join(available)}")
Retry on Network Errors
import time
from tif1.exceptions import NetworkError
def load_with_retry(session, max_retries=3):
for attempt in range(max_retries):
try:
session.load()
return True
except NetworkError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # Exponential backoff
print(f"Retry {attempt + 1}/{max_retries} after {wait_time}s")
time.sleep(wait_time)
else:
print(f"Failed after {max_retries} attempts: {e.message}")
return False