150 Zeilen
5.0 KiB
Python
150 Zeilen
5.0 KiB
Python
"""
|
|
Error Event Entity - Detailliertes Fehler-Event
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from typing import Dict, Any, Optional, List
|
|
from enum import Enum
|
|
import uuid
|
|
|
|
|
|
class ErrorType(Enum):
|
|
"""Typen von Fehlern die auftreten können"""
|
|
RATE_LIMIT = "rate_limit"
|
|
CAPTCHA = "captcha"
|
|
NETWORK = "network"
|
|
VALIDATION = "validation"
|
|
BROWSER = "browser"
|
|
PROXY = "proxy"
|
|
EMAIL = "email"
|
|
TIMEOUT = "timeout"
|
|
AUTHENTICATION = "authentication"
|
|
UNKNOWN = "unknown"
|
|
|
|
|
|
class ErrorSeverity(Enum):
|
|
"""Schweregrad des Fehlers"""
|
|
LOW = "low"
|
|
MEDIUM = "medium"
|
|
HIGH = "high"
|
|
CRITICAL = "critical"
|
|
|
|
|
|
@dataclass
|
|
class ErrorContext:
|
|
"""Kontext-Informationen zum Fehler"""
|
|
url: Optional[str] = None
|
|
action: Optional[str] = None
|
|
step_name: Optional[str] = None
|
|
user_input: Optional[Dict[str, Any]] = None
|
|
browser_state: Optional[Dict[str, Any]] = None
|
|
network_state: Optional[Dict[str, Any]] = None
|
|
screenshot_path: Optional[str] = None
|
|
html_snapshot: Optional[str] = None
|
|
additional_data: Dict[str, Any] = field(default_factory=dict)
|
|
|
|
|
|
@dataclass
|
|
class RecoveryAttempt:
|
|
"""Informationen über Wiederherstellungsversuche"""
|
|
strategy: str
|
|
timestamp: datetime
|
|
successful: bool
|
|
error_message: Optional[str] = None
|
|
duration_seconds: float = 0.0
|
|
|
|
|
|
@dataclass
|
|
class ErrorEvent:
|
|
"""Detailliertes Fehler-Event"""
|
|
|
|
error_id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
timestamp: datetime = field(default_factory=datetime.now)
|
|
error_type: ErrorType = ErrorType.UNKNOWN
|
|
error_message: str = ""
|
|
stack_trace: Optional[str] = None
|
|
context: ErrorContext = field(default_factory=ErrorContext)
|
|
recovery_attempted: bool = False
|
|
recovery_successful: bool = False
|
|
recovery_attempts: List[RecoveryAttempt] = field(default_factory=list)
|
|
|
|
# Fehler-Metadaten
|
|
severity: ErrorSeverity = ErrorSeverity.MEDIUM
|
|
platform: Optional[str] = None
|
|
session_id: Optional[str] = None
|
|
account_id: Optional[str] = None
|
|
correlation_id: Optional[str] = None
|
|
|
|
# Impact-Metriken
|
|
user_impact: bool = True
|
|
system_impact: bool = False
|
|
data_loss: bool = False
|
|
|
|
def add_recovery_attempt(self, attempt: RecoveryAttempt):
|
|
"""Fügt einen Wiederherstellungsversuch hinzu"""
|
|
self.recovery_attempts.append(attempt)
|
|
self.recovery_attempted = True
|
|
if attempt.successful:
|
|
self.recovery_successful = True
|
|
|
|
def get_recovery_success_rate(self) -> float:
|
|
"""Berechnet die Erfolgsrate der Wiederherstellungsversuche"""
|
|
if not self.recovery_attempts:
|
|
return 0.0
|
|
successful = sum(1 for attempt in self.recovery_attempts if attempt.successful)
|
|
return successful / len(self.recovery_attempts)
|
|
|
|
def is_critical(self) -> bool:
|
|
"""Prüft ob der Fehler kritisch ist"""
|
|
return self.severity == ErrorSeverity.CRITICAL or self.data_loss
|
|
|
|
def should_retry(self) -> bool:
|
|
"""Entscheidet ob ein Retry sinnvoll ist"""
|
|
recoverable_types = [
|
|
ErrorType.NETWORK,
|
|
ErrorType.TIMEOUT,
|
|
ErrorType.RATE_LIMIT,
|
|
ErrorType.PROXY
|
|
]
|
|
return (self.error_type in recoverable_types and
|
|
len(self.recovery_attempts) < 3 and
|
|
not self.recovery_successful)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""Konvertiert Event zu Dictionary für Serialisierung"""
|
|
return {
|
|
'error_id': self.error_id,
|
|
'timestamp': self.timestamp.isoformat(),
|
|
'error_type': self.error_type.value,
|
|
'error_message': self.error_message,
|
|
'stack_trace': self.stack_trace,
|
|
'context': {
|
|
'url': self.context.url,
|
|
'action': self.context.action,
|
|
'step_name': self.context.step_name,
|
|
'screenshot_path': self.context.screenshot_path,
|
|
'additional_data': self.context.additional_data
|
|
},
|
|
'recovery_attempted': self.recovery_attempted,
|
|
'recovery_successful': self.recovery_successful,
|
|
'recovery_attempts': [
|
|
{
|
|
'strategy': attempt.strategy,
|
|
'timestamp': attempt.timestamp.isoformat(),
|
|
'successful': attempt.successful,
|
|
'error_message': attempt.error_message,
|
|
'duration_seconds': attempt.duration_seconds
|
|
}
|
|
for attempt in self.recovery_attempts
|
|
],
|
|
'severity': self.severity.value,
|
|
'platform': self.platform,
|
|
'session_id': self.session_id,
|
|
'account_id': self.account_id,
|
|
'correlation_id': self.correlation_id,
|
|
'user_impact': self.user_impact,
|
|
'system_impact': self.system_impact,
|
|
'data_loss': self.data_loss,
|
|
'recovery_success_rate': self.get_recovery_success_rate()
|
|
} |