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.
Overview
The tif1 library provides a structured exception hierarchy for handling different error conditions. All exceptions inherit fromTIF1Error, making it easy to catch library-specific errors.
Exception Hierarchy
TIF1Error (base)
├── DataNotFoundError
│ ├── DriverNotFoundError
│ └── LapNotFoundError
├── NetworkError
├── InvalidDataError
├── CacheError
└── SessionNotLoadedError
Common Exceptions
TIF1Error
Base exception for all tif1 errors:import tif1
try:
session = tif1.get_session(2025, "Invalid GP", "Race")
laps = session.laps
except tif1.TIF1Error as e:
print(f"tif1 error: {e}")
print(f"Context: {e.context}")
DataNotFoundError
Raised when requested data doesn’t exist:import tif1
# Invalid event name
try:
session = tif1.get_session(2025, "Nonexistent GP", "Practice 1")
laps = session.laps
except tif1.DataNotFoundError as e:
print(f"Data not found: {e}")
print("Available events:")
events = tif1.get_events(2025)
for event in events[:5]:
print(f" • {event}")
# Invalid session type
try:
session = tif1.get_session(2025, "Monaco Grand Prix", "Invalid Session")
laps = session.laps
except tif1.DataNotFoundError as e:
print(f"Session not found: {e}")
print("Available sessions:")
sessions = tif1.get_sessions(2025, "Monaco Grand Prix")
for session in sessions:
print(f" • {session}")
DriverNotFoundError
Raised when a driver isn’t in the session:import tif1
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
try:
driver = session.get_driver("XXX") # Invalid driver code
except tif1.DriverNotFoundError as e:
print(f"Driver not found: {e}")
print(f"Context: {e.context}")
print("\nAvailable drivers:")
for _, d in session.drivers_df.iterrows():
print(f" {d['Driver']:3s} - {d['FullName']}")
LapNotFoundError
Raised when a lap doesn’t exist:import tif1
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
ver = session.get_driver("VER")
try:
lap = ver.get_lap(999) # Lap number doesn't exist
except tif1.LapNotFoundError as e:
print(f"Lap not found: {e}")
print(f"Driver: {e.context.get('driver')}")
print(f"Lap number: {e.context.get('lap_number')}")
# Show available laps
ver_laps = ver.laps
if len(ver_laps) > 0:
if hasattr(ver_laps, "iloc"):
min_lap = ver_laps["lap"].min()
max_lap = ver_laps["lap"].max()
else:
lap_nums = list(ver_laps["lap"])
min_lap = min(lap_nums)
max_lap = max(lap_nums)
print(f"Available laps: {min_lap} to {max_lap}")
NetworkError
Raised when network requests fail:import tif1
try:
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
laps = session.laps
except tif1.NetworkError as e:
print(f"Network error: {e}")
print(f"URL: {e.context.get('url')}")
print(f"Status: {e.context.get('status_code')}")
print("\nTips:")
print(" • Check your internet connection")
print(" • Verify CDN availability")
print(" • Try again later (temporary CDN issue)")
InvalidDataError
Raised when data validation fails:import tif1
from tif1.config import get_config
# Enable data validation
config = get_config()
config.set("validate_data", True)
try:
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
laps = session.laps
except tif1.InvalidDataError as e:
print(f"Invalid data: {e}")
print(f"Reason: {e.context.get('reason')}")
CacheError
Raised when cache operations fail:import tif1
try:
cache = tif1.get_cache()
cache.clear()
except tif1.CacheError as e:
print(f"Cache error: {e}")
print("Cache operations failed, continuing without cache...")
SessionNotLoadedError
Raised when accessing data before loading:import tif1
from tif1.core import Session
try:
# Create session without loading
session = Session(
year=2025,
event="Monaco Grand Prix",
session_type="Race"
)
# Try to access data before loading
laps = session.laps # Error: data not loaded
except tif1.SessionNotLoadedError as e:
print(f"Session not loaded: {e}")
print(f"Attribute: {e.context.get('attribute')}")
print("\nLoad session data first:")
print(" session.load(laps=True)")
Error Handling Patterns
Basic Error Handling
import tif1
try:
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
laps = session.laps
print(f"Loaded {len(laps)} laps")
except tif1.TIF1Error as e:
print(f"Error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Specific Error Handling
import tif1
try:
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
ver = session.get_driver("VER")
lap = ver.get_lap(19)
telemetry = lap.telemetry
except tif1.DataNotFoundError as e:
print(f"Data not found: {e}")
# Handle missing data
except tif1.DriverNotFoundError as e:
print(f"Driver not found: {e}")
# Show available drivers
except tif1.LapNotFoundError as e:
print(f"Lap not found: {e}")
# Show available laps
except tif1.NetworkError as e:
print(f"Network error: {e}")
# Retry or use cache
except tif1.TIF1Error as e:
print(f"tif1 error: {e}")
# Generic tif1 error handling
Defensive Programming
Validate inputs before making requests:import tif1
def get_driver_fastest_lap(year, event, session_type, driver_code):
"""Safely get driver's fastest lap with validation."""
try:
# 1. Validate event exists
events = tif1.get_events(year)
if event not in events:
print(f"Event '{event}' not found in {year}")
print(f"Available events: {events[:5]}...")
return None
# 2. Validate session exists
sessions = tif1.get_sessions(year, event)
if session_type not in sessions:
print(f"Session '{session_type}' not found")
print(f"Available sessions: {sessions}")
return None
# 3. Load session
session = tif1.get_session(year, event, session_type)
# 4. Validate driver exists
drivers_df = session.drivers_df
if driver_code not in drivers_df["Driver"].values:
print(f"Driver '{driver_code}' not in session")
print("Available drivers:")
for _, d in drivers_df.iterrows():
print(f" {d['Driver']:3s} - {d['FullName']}")
return None
# 5. Get driver and fastest lap
driver = session.get_driver(driver_code)
fastest = driver.get_fastest_lap()
if len(fastest) > 0:
return fastest
else:
print(f"No valid laps for {driver_code}")
return None
except tif1.TIF1Error as e:
print(f"Error: {e}")
return None
# Usage
fastest = get_driver_fastest_lap(2025, "Monaco Grand Prix", "Race", "VER")
if fastest is not None:
lap_time = fastest["LapTime"].iloc[0]
print(f"VER fastest lap: {lap_time:.3f}s")
Retry with Backoff
Implement custom retry logic for specific errors:import tif1
import time
def load_session_with_retry(year, event, session_type, max_retries=3):
"""Load session with custom retry logic."""
for attempt in range(max_retries):
try:
session = tif1.get_session(year, event, session_type)
laps = session.laps
return session
except tif1.NetworkError as e:
if attempt < max_retries - 1:
wait_time = 2 ** attempt # Exponential backoff
print(f"Network error (attempt {attempt + 1}/{max_retries})")
print(f"Retrying in {wait_time}s...")
time.sleep(wait_time)
else:
print(f"Failed after {max_retries} attempts")
raise
except tif1.DataNotFoundError as e:
# Don't retry for data not found
print(f"Data not found: {e}")
return None
# Usage
session = load_session_with_retry(2025, "Monaco Grand Prix", "Race")
if session:
print(f"Loaded {len(session.laps)} laps")
Graceful Degradation
Provide fallbacks when errors occur:import tif1
def analyze_driver_with_fallback(session, driver_code):
"""Analyze driver with graceful fallback."""
try:
# Try to get driver
driver = session.get_driver(driver_code)
laps = driver.laps
if len(laps) == 0:
print(f"{driver_code} has no laps")
return None
# Try to get fastest lap
try:
fastest = driver.get_fastest_lap()
if len(fastest) > 0:
lap_time = fastest["LapTime"].iloc[0]
return {"driver": driver_code, "fastest": lap_time}
except tif1.LapNotFoundError:
print(f"No fastest lap for {driver_code}")
return None
except tif1.DriverNotFoundError:
# Driver not in session, return None
return None
# Analyze all drivers, skip those not in session
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
drivers_to_check = ["VER", "HAM", "LEC", "NOR", "XXX"]
results = []
for driver_code in drivers_to_check:
result = analyze_driver_with_fallback(session, driver_code)
if result:
results.append(result)
print(f"\nAnalyzed {len(results)} drivers:")
for r in results:
print(f" {r['driver']}: {r['fastest']:.3f}s")
Logging for Debugging
Enable logging to see detailed error information:import logging
import tif1
# Enable debug logging
tif1.setup_logging(logging.DEBUG)
# Or use standard logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
try:
session = tif1.get_session(2025, "Monaco Grand Prix", "Race")
laps = session.laps
except tif1.TIF1Error as e:
logging.error(f"Error loading session: {e}", exc_info=True)
export TIF1_LOG_LEVEL=DEBUG
python your_script.py
{
"log_level": "DEBUG"
}
Complete Error Handling Example
import logging
import tif1
# Setup logging
tif1.setup_logging(logging.INFO)
def safe_driver_analysis(year, event, session_type, driver_code):
"""Comprehensive error handling example."""
print(f"\nAnalyzing {driver_code} in {event} {session_type}")
print("=" * 60)
try:
# 1. Get available events
events = tif1.get_events(year)
if event not in events:
print(f"✗ Event not found")
print(f" Tip: Use tif1.get_events({year}) to list events")
return False
print("✓ Event found")
# 2. Get available sessions
sessions = tif1.get_sessions(year, event)
if session_type not in sessions:
print(f"✗ Session not found")
print(f" Available: {sessions}")
return False
print("✓ Session found")
# 3. Load session
try:
session = tif1.get_session(year, event, session_type)
print("✓ Session loaded")
except tif1.NetworkError as e:
print(f"✗ Network error: {e}")
print(" Tip: Check internet connection")
return False
# 4. Validate driver exists
drivers_df = session.drivers_df
if driver_code not in drivers_df["Driver"].values:
print(f"✗ Driver {driver_code} not in session")
print(" Available drivers:")
for _, d in drivers_df.head(5).iterrows():
print(f" {d['Driver']:3s} - {d['FullName']}")
return False
print(f"✓ Driver {driver_code} found")
# 5. Get driver data
driver = session.get_driver(driver_code)
laps = driver.laps
if len(laps) == 0:
print(f"✗ No laps available for {driver_code}")
return False
print(f"✓ {len(laps)} laps loaded")
# 6. Get fastest lap
fastest = driver.get_fastest_lap()
if len(fastest) > 0:
lap_time = fastest["LapTime"].iloc[0]
lap_num = fastest["LapNumber"].iloc[0]
print(f"✓ Fastest lap: {lap_time:.3f}s (Lap {lap_num})")
else:
print("✗ No valid lap times")
return False
# 7. Get telemetry
try:
lap = driver.get_lap(int(lap_num))
telemetry = lap.telemetry
print(f"✓ Telemetry loaded: {len(telemetry)} points")
print(f" Max speed: {telemetry['Speed'].max():.1f} km/h")
except tif1.LapNotFoundError as e:
print(f"✗ Lap telemetry not available: {e}")
return True
except tif1.TIF1Error as e:
print(f"✗ tif1 error: {e}")
return False
except Exception as e:
print(f"✗ Unexpected error: {e}")
logging.exception("Unexpected error")
return False
# Test the function
print("ERROR HANDLING DEMONSTRATION")
print("=" * 60)
# Valid request
safe_driver_analysis(2025, "Monaco Grand Prix", "Race", "VER")
# Invalid driver
safe_driver_analysis(2025, "Monaco Grand Prix", "Race", "XXX")
# Invalid event
safe_driver_analysis(2025, "Invalid GP", "Race", "VER")
Next Steps
- Learn about configuration for error handling settings
- Explore async loading for error handling in async context
- Understand caching for cache-related errors