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()
    ]
)