mrradix commited on
Commit
013c3e4
·
verified ·
1 Parent(s): 278a9dc

Update utils/error_handling.py

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