File size: 4,198 Bytes
2929135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# src/utils/error_handlers.py
from typing import Dict, Any, Optional, Callable
from functools import wraps
import traceback
from .logger import setup_logger

logger = setup_logger(__name__)

class HealthcareError(Exception):
    """Base exception class for healthcare operations"""
    def __init__(self, message: str, error_code: str, details: Optional[Dict] = None):
        self.message = message
        self.error_code = error_code
        self.details = details or {}
        super().__init__(self.message)

class ValidationError(HealthcareError):
    """Raised when input validation fails"""
    def __init__(self, message: str, details: Optional[Dict] = None):
        super().__init__(
            message=message,
            error_code="INPUT_VALIDATION_ERROR",
            details=details
        )

class ProcessingError(HealthcareError):
    """Raised when processing operations fail"""
    pass

class ResourceError(HealthcareError):
    """Raised when resource-related operations fail"""
    pass

class ErrorHandler:
    @staticmethod
    def validate_input(input_text: str) -> None:
        """Validate input text before processing"""
        if not input_text or not input_text.strip():
            raise ValidationError(
                message="Input text cannot be empty",
                details={"provided_input": input_text}
            )

    @staticmethod
    def handle_error(error: Exception) -> Dict[str, Any]:
        """Handle different types of errors and return appropriate response"""
        if isinstance(error, ValidationError):
            logger.error(f"Validation Error: {error.message}", 
                        extra={"error_code": error.error_code, "details": error.details})
            raise error  # Re-raise ValidationError
        elif isinstance(error, HealthcareError):
            logger.error(f"Healthcare Error: {error.message}", 
                        extra={"error_code": error.error_code, "details": error.details})
            return {
                "error": True,
                "error_code": error.error_code,
                "message": error.message,
                "details": error.details
            }
        else:
            logger.error(f"Unexpected Error: {str(error)}\n{traceback.format_exc()}")
            return {
                "error": True,
                "error_code": "UNEXPECTED_ERROR",
                "message": "An unexpected error occurred",
                "details": {"error_type": type(error).__name__}
            }

    @staticmethod
    def error_decorator(func: Callable) -> Callable:
        """Decorator for handling errors in functions"""
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except ValidationError:
                # Let ValidationError propagate up
                raise
            except Exception as e:
                return ErrorHandler.handle_error(e)
        return wrapper
    
    @staticmethod
    def retry_operation(
        operation: Callable,
        max_retries: int = 3,
        retry_delay: float = 1.0
    ) -> Any:
        """
        Retry an operation with exponential backoff
        """
        from time import sleep
        
        for attempt in range(max_retries):
            try:
                return operation()
            except Exception as e:
                if attempt == max_retries - 1:
                    raise
                
                logger.warning(
                    f"Operation failed (attempt {attempt + 1}/{max_retries}): {str(e)}"
                )
                sleep(retry_delay * (2 ** attempt))

    @staticmethod
    def safe_execute(
        operation: Callable,
        error_code: str,
        default_value: Any = None
    ) -> Any:
        """
        Safely execute an operation with error handling
        """
        try:
            return operation()
        except Exception as e:
            logger.error(f"Operation failed: {str(e)}")
            raise HealthcareError(
                message=f"Operation failed: {str(e)}",
                error_code=error_code
            )# Error handling utilities implementation