MorphGuard / src /error_handling.py
juanquy's picture
Initial clean commit of modular MorphGuard
2978bba
Raw
History Blame Contribute Delete
5.29 kB
"""
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"
)