🛡️ Error Handling¶
Eones defines a robust system of specific exceptions for different types of errors, all inheriting from a common base class EonesError.
Exception Hierarchy¶
from eones.errors import (
EonesError, # Base exception
InvalidTimezoneError, # Invalid timezone
InvalidDateFormatError, # Invalid date format
InvalidDurationFormatError # Invalid duration format
)
EonesError - Base Exception¶
All custom Eones exceptions inherit from this base class:
class EonesError(Exception):
pass
This allows catching any Eones-specific error:
try:
date = Eones("invalid-date", tz="Nonexistent/Zone")
except EonesError as e:
print(f"Eones error: {e}")
InvalidTimezoneError¶
Raised when an unrecognized timezone is provided:
try:
date = Eones("2024-01-01", tz="Nonexistent/Zone")
except InvalidTimezoneError as e:
print(f"Invalid timezone: {e}")
# Use default timezone
date = Eones("2024-01-01") # UTC by default
InvalidDateFormatError¶
Raised when the date string cannot be parsed correctly:
try:
date = Eones("completely-invalid-date")
except InvalidDateFormatError as e:
print(f"Invalid date format: {e}")
# Try with specific format
date = Eones("2024-01-01", formats=["%Y-%m-%d"])
InvalidDurationFormatError¶
Raised when an ISO 8601 duration string is invalid:
from eones.delta import Delta
try:
delta = Delta.from_iso("P1Y2M3D4H5M6S-INVALID")
except InvalidDurationFormatError as e:
print(f"Invalid ISO duration format: {e}")
# Create delta manually
delta = Delta(years=1, months=2, days=3, hours=4, minutes=5, seconds=6)
Robust Error Handling¶
Safe Creation Function¶
def create_safe_date(date_str, tz_str=None):
"""Creates a date safely with error handling."""
try:
return Eones(date_str, tz=tz_str)
except InvalidDateFormatError:
print(f"Invalid date format: {date_str}")
return None
except InvalidTimezoneError:
print(f"Invalid timezone: {tz_str}, using UTC")
return Eones(date_str) # UTC by default
except EonesError as e:
print(f"General Eones error: {e}")
return None
# Usage
date = create_safe_date("2024-12-25", "Europe/Madrid")
if date:
print(f"Date created: {date.format('%Y-%m-%d %Z')}")
Multiple Format Handling¶
def parse_flexible_date(date_str):
"""Attempts to parse a date with multiple strategies."""
formats = [
"%Y-%m-%d",
"%d/%m/%Y",
"%d-%m-%Y",
"%Y-%m-%d %H:%M:%S"
]
for format_str in formats:
try:
return Eones(date_str, formats=[format_str])
except InvalidDateFormatError:
continue
# If no format works
raise InvalidDateFormatError(f"Could not parse date: {date_str}")
# Usage
try:
date = parse_flexible_date("25/12/2024")
print(f"Parsed date: {date.format('%Y-%m-%d')}")
except InvalidDateFormatError as e:
print(f"Error: {e}")
User Input Validation¶
def validate_user_input(date_input, tz_input=None):
"""Validates and processes user input with detailed feedback."""
errors = []
# Validate date
date = None
try:
date = Eones(date_input, tz=tz_input)
except InvalidDateFormatError:
errors.append(f"Invalid date format: '{date_input}'")
errors.append("Valid formats: YYYY-MM-DD, DD/MM/YYYY, DD-MM-YYYY")
except InvalidTimezoneError:
errors.append(f"Invalid timezone: '{tz_input}'")
errors.append("Valid timezone example: 'Europe/Madrid', 'America/New_York'")
# Try without timezone
try:
date = Eones(date_input)
errors.append("Using UTC as default timezone")
except InvalidDateFormatError:
errors.append("Could not parse date without timezone either")
except EonesError as e:
errors.append(f"Unexpected error: {e}")
return date, errors
# Usage
date, errors = validate_user_input("25/12/2024", "Europe/Madrid")
if errors:
for error in errors:
print(f"⚠️ {error}")
if date:
print(f"✅ Valid date: {date.format('%Y-%m-%d %Z')}")
Error Logging¶
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def process_date_with_logging(date_str, tz_str=None):
"""Processes date with detailed error logging."""
try:
date = Eones(date_str, tz=tz_str)
logger.info(f"Date processed successfully: {date.format('%Y-%m-%d %Z')}")
return date
except InvalidDateFormatError as e:
logger.error(f"Date format error: {e}")
logger.info(f"Input received: '{date_str}'")
raise
except InvalidTimezoneError as e:
logger.warning(f"Invalid timezone: {e}")
logger.info(f"Retrying with UTC...")
return Eones(date_str) # Fallback to UTC
except EonesError as e:
logger.error(f"Unexpected Eones error: {e}")
raise
Exception Usage Contexts¶
These exceptions are used internally in:
parser.py: When parsing invalid dates or durationsDateandDelta: When initializing objects with incorrect datainterface.py: When validating user inputsConversion methods: When converting between formats
Best Practices¶
Always catch specific exceptions before the base exception
Provide helpful error messages to the user
Implement sensible fallbacks when possible
Log errors for debugging and monitoring
Validate inputs before processing when critical