File size: 3,874 Bytes
013c3e4 d249ccb 013c3e4 c087535 d249ccb 013c3e4 65e7d4d 013c3e4 d249ccb 013c3e4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
"""
Error handling utilities for the application
"""
import logging
import traceback
from functools import wraps
from typing import Any, Callable, Optional, Union
import streamlit as st
class DataError(Exception):
"""Custom exception for data-related errors"""
pass
class ValidationError(Exception):
"""Custom exception for validation errors"""
pass
class ProcessingError(Exception):
"""Custom exception for processing errors"""
pass
def handle_data_exceptions(func: Callable) -> Callable:
"""
Decorator to handle data-related exceptions
"""
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except (DataError, ValidationError, ProcessingError) as e:
logging.error(f"Data error in {func.__name__}: {str(e)}")
st.error(f"Data error: {str(e)}")
return None
except FileNotFoundError as e:
logging.error(f"File not found in {func.__name__}: {str(e)}")
st.error(f"File not found: {str(e)}")
return None
except PermissionError as e:
logging.error(f"Permission error in {func.__name__}: {str(e)}")
st.error(f"Permission error: {str(e)}")
return None
except Exception as e:
logging.error(f"Unexpected error in {func.__name__}: {str(e)}")
logging.error(traceback.format_exc())
st.error(f"An unexpected error occurred: {str(e)}")
return None
return wrapper
def handle_api_exceptions(func: Callable) -> Callable:
"""
Decorator to handle API-related exceptions
"""
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except ConnectionError as e:
logging.error(f"Connection error in {func.__name__}: {str(e)}")
st.error("Connection error. Please check your internet connection.")
return None
except TimeoutError as e:
logging.error(f"Timeout error in {func.__name__}: {str(e)}")
st.error("Request timed out. Please try again.")
return None
except Exception as e:
logging.error(f"API error in {func.__name__}: {str(e)}")
st.error(f"API error: {str(e)}")
return None
return wrapper
def log_error(message: str, error: Optional[Exception] = None):
"""
Log an error message with optional exception details
"""
if error:
logging.error(f"{message}: {str(error)}")
logging.error(traceback.format_exc())
else:
logging.error(message)
def display_error(message: str, error_type: str = "error"):
"""
Display an error message in the Streamlit interface
"""
if error_type == "warning":
st.warning(message)
elif error_type == "info":
st.info(message)
else:
st.error(message)
def validate_input(value: Any, value_type: type, field_name: str) -> bool:
"""
Validate input value and type
"""
if value is None:
raise ValidationError(f"{field_name} cannot be None")
if not isinstance(value, value_type):
raise ValidationError(f"{field_name} must be of type {value_type.__name__}")
return True
def safe_execute(func: Callable, *args, **kwargs) -> tuple[bool, Any]:
"""
Safely execute a function and return success status and result
"""
try:
result = func(*args, **kwargs)
return True, result
except Exception as e:
log_error(f"Error executing {func.__name__}", e)
return False, str(e)
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
) |