File size: 5,293 Bytes
2978bba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""
Minimal implementation of error handling for API utils testing.

This is a placeholder implementation to allow the api_utils tests to run.
In a real deployment, this would be replaced by the full error handling system.
"""

from enum import Enum
from typing import Dict, Any, Optional, List, Type
import logging

class ErrorCode(str, Enum):
    """Error codes for different categories of errors."""
    # General errors (1000-1099)
    UNKNOWN_ERROR = "MG-1000"
    INTERNAL_ERROR = "MG-1001"
    INVALID_INPUT = "MG-1002"
    UNAUTHORIZED = "MG-1003"
    FORBIDDEN = "MG-1004"
    NOT_FOUND = "MG-1005"
    TIMEOUT = "MG-1006"
    RATE_LIMITED = "MG-1007"
    SERVICE_UNAVAILABLE = "MG-1008"
    
    # API and network errors (1100-1199)
    API_ERROR = "MG-1100"
    NETWORK_ERROR = "MG-1101"
    OFFLINE = "MG-1102"
    REQUEST_FAILED = "MG-1103"

class ErrorSeverity(str, Enum):
    """Severity levels for errors."""
    DEBUG = "debug"
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"

class ErrorCategory(str, Enum):
    """Categories of errors for grouping and analysis."""
    GENERAL = "general"
    API = "api"
    AUTHENTICATION = "authentication"
    FILE = "file"
    MODEL = "model"
    DATABASE = "database"
    EXTERNAL_SERVICE = "external_service"
    CONFIGURATION = "configuration"
    JOB = "job"

class MGError(Exception):
    """Base exception class for MorphGuard errors."""
    
    def __init__(
        self,
        message: str,
        code: ErrorCode = ErrorCode.UNKNOWN_ERROR,
        severity: ErrorSeverity = ErrorSeverity.ERROR,
        category: ErrorCategory = ErrorCategory.GENERAL,
        details: Optional[Dict[str, Any]] = None,
        original_error: Optional[Exception] = None,
        retry_possible: bool = False,
        user_message: Optional[str] = None,
        http_status: Optional[int] = None
    ):
        """
        Initialize the error.
        
        Args:
            message: Technical error message
            code: Error code
            severity: Error severity
            category: Error category
            details: Additional error details
            original_error: Original exception that caused this error
            retry_possible: Whether the operation could be retried
            user_message: Human-readable message suitable for end users
            http_status: HTTP status code for API responses
        """
        self.message = message
        self.code = code
        self.severity = severity
        self.category = category
        self.details = details or {}
        self.original_error = original_error
        self.retry_possible = retry_possible
        self.user_message = user_message or message
        self.http_status = http_status
        
        # Initialize parent Exception class
        super().__init__(self.message)

class APIError(MGError):
    """Error related to API operations."""
    
    def __init__(
        self,
        message: str,
        code: ErrorCode = ErrorCode.API_ERROR,
        details: Optional[Dict[str, Any]] = None,
        original_error: Optional[Exception] = None,
        retry_possible: bool = True,
        user_message: Optional[str] = None,
        http_status: Optional[int] = 500
    ):
        super().__init__(
            message=message,
            code=code,
            severity=ErrorSeverity.ERROR,
            category=ErrorCategory.API,
            details=details,
            original_error=original_error,
            retry_possible=retry_possible,
            user_message=user_message,
            http_status=http_status
        )

class NetworkError(MGError):
    """Error related to network operations."""
    
    def __init__(
        self,
        message: str,
        code: ErrorCode = ErrorCode.NETWORK_ERROR,
        details: Optional[Dict[str, Any]] = None,
        original_error: Optional[Exception] = None,
        retry_possible: bool = True,
        user_message: Optional[str] = None
    ):
        super().__init__(
            message=message,
            code=code,
            severity=ErrorSeverity.ERROR,
            category=ErrorCategory.API,
            details=details,
            original_error=original_error,
            retry_possible=retry_possible,
            user_message=user_message,
            http_status=503
        )

def handle_exception(
    exc: Exception,
    default_error_class: Type[MGError] = MGError,
    default_error_code: ErrorCode = ErrorCode.UNKNOWN_ERROR,
    default_message: str = "An unexpected error occurred",
    logger: Optional[logging.Logger] = None
) -> MGError:
    """
    Convert any exception to a MGError.
    
    Args:
        exc: The exception to handle
        default_error_class: Default error class to use if exc is not a MGError
        default_error_code: Default error code to use
        default_message: Default message to use
        logger: Logger to use for logging
        
    Returns:
        A MGError instance
    """
    if isinstance(exc, MGError):
        return exc
    
    # Create a new MGError
    return default_error_class(
        message=str(exc) or default_message,
        code=default_error_code,
        original_error=exc,
        user_message="An unexpected error occurred"
    )