institutional-trader/backend/python_service/utils/error_handler.py

79 lines
2.1 KiB
Python

"""
Error handling utilities
"""
from typing import Optional, Dict, Any
import traceback
from utils.logger import logger
class ProcessingError(Exception):
"""Base exception for processing errors"""
pass
class DataValidationError(ProcessingError):
"""Raised when data validation fails"""
pass
class DatabaseError(ProcessingError):
"""Raised when database operations fail"""
pass
def handle_processing_error(
error: Exception,
context: Optional[Dict[str, Any]] = None,
raise_error: bool = True
) -> Optional[Dict[str, Any]]:
"""
Handle processing errors with logging and optional error response
Args:
error: The exception that occurred
context: Additional context about where the error occurred
raise_error: Whether to re-raise the error
Returns:
Error response dict if not raising, None otherwise
"""
error_info = {
'error_type': type(error).__name__,
'error_message': str(error),
'context': context or {}
}
# Log the error
logger.error(
f"Processing error: {error_info['error_type']} - {error_info['error_message']}",
extra={'context': context, 'traceback': traceback.format_exc()}
)
if raise_error:
raise error
return error_info
def validate_dataframe(df, required_columns: list, operation: str = "operation"):
"""Validate DataFrame has required columns"""
if df is None or df.empty:
raise DataValidationError(f"DataFrame is empty for {operation}")
missing_columns = [col for col in required_columns if col not in df.columns]
if missing_columns:
raise DataValidationError(
f"Missing required columns for {operation}: {missing_columns}"
)
def safe_divide(numerator, denominator, default=0.0):
"""Safely divide two numbers, returning default if denominator is zero or None"""
if denominator is None or denominator == 0:
return default
try:
return numerator / denominator
except (TypeError, ZeroDivisionError):
return default