# Exception System Advanced Features ## Übersicht Das Exception-System wurde um 10 erweiterte Features erweitert, die in drei Phasen implementiert wurden: - **Phase 1 (Foundation)**: Rate Limiting, Context Caching, Performance Tracking - **Phase 2 (User Experience)**: User-Friendly Messages, Localization - **Phase 3 (Advanced)**: Recovery/Retry, Pattern Detection, Correlation, Metrics, Health Checks Alle Features sind optional und können einzeln aktiviert werden. Sie folgen den Framework-Prinzipien (final, readonly, Value Objects, Composition over Inheritance). --- ## Phase 1: Foundation Features ### 1. Exception Rate Limiting & Throttling **Ziel**: Verhindert Log-Spam durch wiederholte gleiche Exceptions **Komponenten**: - `ExceptionFingerprint` - Generiert eindeutige Fingerprints für Exception-Gruppierung - `ExceptionRateLimitConfig` - Konfiguration für Thresholds und Time Windows - `ExceptionRateLimiter` - Rate Limiter mit Cache-basiertem Tracking **Verwendung**: ```php use App\Framework\ExceptionHandling\RateLimit\ExceptionRateLimiter; use App\Framework\ExceptionHandling\RateLimit\ExceptionRateLimitConfig; use App\Framework\Core\ValueObjects\Duration; // Konfiguration erstellen $config = ExceptionRateLimitConfig::withLimits( maxExceptions: 10, timeWindow: Duration::fromSeconds(60) ); // Rate Limiter erstellen $rateLimiter = new ExceptionRateLimiter($cache, $config); // In ErrorKernel integriert (automatisch) // Exceptions werden automatisch rate-limited, wenn Threshold erreicht wird ``` **Konfiguration**: - `maxExceptions`: Maximale Anzahl gleicher Exceptions pro Time Window (Default: 10) - `timeWindow`: Time Window für Rate Limiting (Default: 60 Sekunden) - `skipLoggingOnLimit`: Skip Logging wenn Rate Limit erreicht (Default: true) - `skipAuditOnLimit`: Skip Audit Logging wenn Rate Limit erreicht (Default: true) - `trackMetricsOnLimit`: Track Metriken auch bei Rate Limit (Default: true) **Fingerprint-Generierung**: - Basierend auf Exception-Klasse, normalisierter Message, File/Line - Optional: Component und Operation aus Context für präzisere Gruppierung - Normalisierung entfernt variable Teile (UUIDs, Timestamps, Zahlen, etc.) --- ### 2. Exception Context Caching **Ziel**: Performance-Optimierung durch Caching von häufig verwendeten Context-Daten **Komponenten**: - `ExceptionContextCache` - Cache-Wrapper für Context-Daten - Integration in `ExceptionContextBuilder` - Automatischer Cache-Lookup **Verwendung**: ```php use App\Framework\ExceptionHandling\Context\ExceptionContextCache; use App\Framework\ExceptionHandling\Context\ExceptionContextBuilder; // Context Cache erstellen $contextCache = new ExceptionContextCache($cache); // Context Builder mit Cache $builder = new ExceptionContextBuilder( errorScope: $errorScope, contextCache: $contextCache ); // Automatischer Cache-Lookup beim buildFromRequest() $context = $builder->buildFromRequest($request); ``` **Cache-Levels**: - **Request-Level**: TTL 10 Minuten (spezifischste) - **Session-Level**: TTL 10 Minuten - **User-Level**: TTL 30 Minuten (am wenigsten spezifisch) **Cache-Invalidation**: ```php // Manuelle Invalidation bei Context-Änderungen $contextCache->invalidateRequest($requestId); $contextCache->invalidateSession($sessionId); $contextCache->invalidateUser($userId); ``` --- ### 3. Exception Performance Tracking **Ziel**: Tracking von Performance-Impact pro Exception-Typ **Komponenten**: - `ExceptionPerformanceMetrics` - Value Object für Metriken - `ExceptionPerformanceTracker` - Performance-Tracking **Verwendung**: ```php use App\Framework\ExceptionHandling\Performance\ExceptionPerformanceTracker; $tracker = new ExceptionPerformanceTracker(); // Start tracking $startData = $tracker->start(); // ... exception occurs ... // End tracking $metrics = $tracker->end($startData, $exception, $context); // Metriken enthalten: // - executionTimeMs: Ausführungszeit in Millisekunden // - memoryDeltaBytes: Memory-Delta in Bytes // - cpuUsagePercent: CPU-Usage in Prozent (wenn verfügbar) ``` **Integration**: - Metriken werden automatisch in `ExceptionContextData::metadata['performance']` gespeichert - Kann mit `MetricsCollector` integriert werden für Monitoring --- ## Phase 2: User Experience Features ### 4. User-Friendly Exception Messages **Ziel**: Übersetzung von technischen Exception-Messages zu benutzerfreundlichen Texten **Komponenten**: - `UserFriendlyMessage` - Value Object für User-Messages - `ExceptionMessageTranslator` - Message-Übersetzung mit Template-System **Verwendung**: ```php use App\Framework\ExceptionHandling\Translation\ExceptionMessageTranslator; use App\Framework\ExceptionHandling\Translation\UserFriendlyMessage; // Templates definieren $templates = [ \App\Framework\Exception\DatabaseException::class => [ 'message' => 'Database connection failed. Please try again later.', 'title' => 'Database Error', 'help' => 'If this problem persists, please contact support.' ], \App\Framework\Exception\ValidationException::class => [ 'message' => 'Please check your input and try again.', 'title' => 'Validation Error' ] ]; // Translator erstellen $translator = new ExceptionMessageTranslator( templates: $templates, isDebugMode: false ); // Message übersetzen $userMessage = $translator->translate($exception, $context); // $userMessage->message: User-friendly message // $userMessage->title: Optional title // $userMessage->helpText: Optional help text // $userMessage->technicalMessage: Original technical message (für Debugging) ``` **Template-Variablen**: - `{exception_message}` - Original Exception-Message - `{exception_class}` - Exception-Klasse - `{operation}` - Operation aus Context - `{component}` - Component aus Context **Integration**: - Automatisch in `ResponseErrorRenderer` integriert - In Debug-Mode werden technische Messages angezeigt - In Production werden User-Friendly Messages verwendet --- ### 5. Exception Localization **Ziel**: i18n-Support für Exception-Messages basierend auf User-Locale **Komponenten**: - `ExceptionLocalizer` - Lokalisierung mit Fallback-Chain **Verwendung**: ```php use App\Framework\ExceptionHandling\Localization\ExceptionLocalizer; // Übersetzungen definieren $translations = [ 'de' => [ \App\Framework\Exception\DatabaseException::class => [ 'message' => 'Datenbankverbindung fehlgeschlagen. Bitte versuchen Sie es später erneut.', 'title' => 'Datenbankfehler' ] ], 'en' => [ \App\Framework\Exception\DatabaseException::class => [ 'message' => 'Database connection failed. Please try again later.', 'title' => 'Database Error' ] ] ]; // Localizer erstellen $localizer = new ExceptionLocalizer( translations: $translations, defaultLocale: 'en' ); // Locale aus Context extrahieren $locale = $localizer->getLocale($context); // Übersetzungen für Locale abrufen $localeTranslations = $localizer->getTranslations($locale); // Fallback-Chain: [user_locale, default_locale, 'en'] $fallbackChain = $localizer->getFallbackChain($locale); ``` **Locale-Extraktion**: - Aus `ExceptionContextData::metadata['locale']` - Fallback zu Default-Locale - Fallback zu 'en' als letzte Option **Integration**: - Wird von `ExceptionMessageTranslator` verwendet - Locale sollte in `ExceptionContextData::metadata['locale']` gespeichert werden --- ## Phase 3: Advanced Features ### 6. Exception Recovery & Retry Logic **Ziel**: Automatische Retry-Logik für temporäre Exceptions **Komponenten**: - `RetryStrategy` - Retry-Strategien (Exponential Backoff, Linear, Fixed) - `ExceptionRecoveryManager` - Recovery-Manager - `RetryableException` - Marker-Interface **Verwendung**: ```php use App\Framework\ExceptionHandling\Recovery\ExceptionRecoveryManager; use App\Framework\ExceptionHandling\Recovery\RetryableException; use App\Framework\Exception\ExceptionMetadata; // Retryable Exception implementieren final class NetworkException extends \Exception implements RetryableException { } // Exception mit Retry-Config erstellen $metadata = ExceptionMetadata::withRetry( retryAfter: 1000 // Base delay in milliseconds )->withMaxRetries(3) ->withRetryStrategy('exponential_backoff'); // Recovery Manager $recoveryManager = new ExceptionRecoveryManager(); // Prüfen ob Retry nötig if ($recoveryManager->shouldRetry($exception, $metadata)) { $delay = $recoveryManager->getRetryDelay($exception, $metadata, $attemptNumber); // Retry nach $delay Millisekunden } ``` **Retry-Strategien**: - **Exponential Backoff** (Default): `baseDelay * 2^(attempt-1)` - **Linear**: `baseDelay * attempt` - **Fixed**: `baseDelay` (konstant) **ExceptionMetadata Erweiterungen**: - `maxRetries`: Maximale Anzahl Retries (Default: 3) - `retryStrategy`: Retry-Strategie (Default: 'exponential_backoff') - `retryAfter`: Base Delay in Millisekunden **Retryable Exceptions**: - Exceptions die `RetryableException` implementieren - Exceptions mit bestimmten Namen-Patterns (NetworkException, TimeoutException, etc.) --- ### 7. Exception Pattern Detection & Auto-Fix Suggestions **Ziel**: ML-basierte Pattern-Erkennung mit Fix-Vorschlägen **Komponenten**: - `ExceptionPattern` - Value Object für Patterns - `FixSuggestion` - Value Object für Fix-Vorschläge - `ExceptionPatternDetector` - Pattern-Detection **Verwendung**: ```php use App\Framework\ExceptionHandling\PatternDetection\ExceptionPatternDetector; use App\Framework\ExceptionHandling\PatternDetection\FixSuggestion; // Knowledge Base definieren $knowledgeBase = [ \App\Framework\Exception\DatabaseException::class => [ 'description' => 'Database connection timeout', 'fixes' => [ [ 'title' => 'Check connection pool size', 'description' => 'Increase database connection pool size', 'code' => '$config->setMaxConnections(50);', 'confidence' => 'high' ], [ 'title' => 'Check database server', 'description' => 'Verify database server is running and accessible', 'confidence' => 'medium' ] ] ] ]; // Pattern Detector erstellen $detector = new ExceptionPatternDetector($knowledgeBase); // Patterns erkennen $patterns = $detector->detect($exception, $context); foreach ($patterns as $pattern) { echo $pattern->description . "\n"; foreach ($pattern->fixSuggestions as $fix) { echo " - " . $fix->title . ": " . $fix->description . "\n"; } } ``` **Integration**: - Kann in `ErrorAggregator` integriert werden - Patterns werden in `ExceptionContextData::metadata['patterns']` gespeichert --- ### 8. Exception Correlation & Root Cause Analysis **Ziel**: Verknüpfung verwandter Exceptions für Root-Cause-Analyse **Komponenten**: - `ExceptionCorrelation` - Value Object für Korrelationen - `ExceptionCorrelationEngine` - Correlation-Engine **Verwendung**: ```php use App\Framework\ExceptionHandling\Correlation\ExceptionCorrelationEngine; $correlationEngine = new ExceptionCorrelationEngine($cache); // Exception korrelieren $correlation = $correlationEngine->correlate($exception, $context); // Correlation-Daten: // - correlationKey: Request-ID, Session-ID oder User-ID // - exceptionIds: Array von verwandten Exception-IDs // - rootCauseId: ID der ersten Exception (Root Cause) ``` **Correlation-Keys**: - **Request-ID** (höchste Priorität): Alle Exceptions in derselben Request - **Session-ID**: Alle Exceptions in derselben Session - **User-ID**: Alle Exceptions für denselben User **Root Cause Analysis**: - Erste Exception in Correlation-Chain ist Root Cause - Alle weiteren Exceptions sind Folge-Exceptions **Integration**: - Correlation-Daten werden in `ExceptionContextData::metadata['correlations']` gespeichert - Kann für Exception-Graph-Visualisierung verwendet werden --- ### 9. Exception Metrics & Monitoring Integration **Ziel**: Integration mit Monitoring-Systemen (Prometheus, StatsD) **Komponenten**: - `ExceptionMetrics` - Value Object für Metriken - `ExceptionMetricsCollector` - Metrics-Collector - `PrometheusExporter` - Prometheus-Export **Verwendung**: ```php use App\Framework\ExceptionHandling\Metrics\ExceptionMetricsCollector; use App\Framework\ExceptionHandling\Metrics\PrometheusExporter; $collector = new ExceptionMetricsCollector($cache); // Exception-Metrik aufzeichnen $collector->record($exception, $context, $executionTimeMs); // Metriken abrufen $metrics = $collector->getMetrics(); // Prometheus-Format exportieren $exporter = new PrometheusExporter(); $prometheusMetrics = $exporter->export($metrics); // Output: // exception_total 42 // exception_by_class{exception_class="DatabaseException"} 10 // exception_by_component{component="UserService"} 5 // exception_average_execution_time_ms 125.50 ``` **Metriken**: - `totalCount`: Gesamtanzahl Exceptions - `byClass`: Anzahl pro Exception-Klasse - `byComponent`: Anzahl pro Component - `averageExecutionTimeMs`: Durchschnittliche Ausführungszeit **Integration**: - Kann in `ProductionMetricsController` integriert werden - Metriken werden im Prometheus-Format exportiert - Real-time Aggregation über Time-Windows --- ### 10. Exception Health Checks & Circuit Breakers **Ziel**: Circuit Breaker Pattern für Exception-basierte Health Checks **Komponenten**: - `ExceptionHealthChecker` - Health Checker **Verwendung**: ```php use App\Framework\ExceptionHandling\Health\ExceptionHealthChecker; use App\Framework\ExceptionHandling\Metrics\ExceptionMetricsCollector; $metricsCollector = new ExceptionMetricsCollector($cache); $healthChecker = new ExceptionHealthChecker( metricsCollector: $metricsCollector, errorRateThreshold: 0.1, // 10% Error Rate timeWindowSeconds: 60 ); // Health Check durchführen $result = $healthChecker->check(); // Status: // - Healthy: Error Rate < 5% // - Warning: Error Rate 5-10% // - Unhealthy: Error Rate > 10% ``` **Health Check Status**: - **Healthy**: Error Rate unterhalb des Thresholds - **Warning**: Error Rate bei 50% des Thresholds - **Unhealthy**: Error Rate oberhalb des Thresholds **Integration**: - Implementiert `HealthCheckInterface` - Kann in `HealthCheckManager` registriert werden - Nutzt bestehende `CircuitBreaker` Infrastruktur --- ## DI Container Integration ### Beispiel-Konfiguration ```php // Exception Rate Limiter $container->bind(ExceptionRateLimitConfig::class, function() { return ExceptionRateLimitConfig::withLimits( maxExceptions: 10, timeWindow: Duration::fromSeconds(60) ); }); $container->singleton(ExceptionRateLimiter::class, function($container) { return new ExceptionRateLimiter( cache: $container->get(Cache::class), config: $container->get(ExceptionRateLimitConfig::class) ); }); // Exception Context Cache $container->singleton(ExceptionContextCache::class, function($container) { return new ExceptionContextCache( cache: $container->get(Cache::class) ); }); // Exception Context Builder $container->singleton(ExceptionContextBuilder::class, function($container) { return new ExceptionContextBuilder( errorScope: $container->get(ErrorScope::class), contextCache: $container->get(ExceptionContextCache::class) ); }); // Exception Performance Tracker $container->singleton(ExceptionPerformanceTracker::class, function() { return new ExceptionPerformanceTracker(); }); // Exception Message Translator $container->singleton(ExceptionMessageTranslator::class, function($container) { $templates = require __DIR__ . '/config/exception_messages.php'; return new ExceptionMessageTranslator( templates: $templates, isDebugMode: $container->get('config')->get('app.debug', false) ); }); // Exception Localizer $container->singleton(ExceptionLocalizer::class, function() { $translations = require __DIR__ . '/config/exception_translations.php'; return new ExceptionLocalizer( translations: $translations, defaultLocale: 'en' ); }); // Exception Recovery Manager $container->singleton(ExceptionRecoveryManager::class, function() { return new ExceptionRecoveryManager(); }); // Exception Pattern Detector $container->singleton(ExceptionPatternDetector::class, function() { $knowledgeBase = require __DIR__ . '/config/exception_patterns.php'; return new ExceptionPatternDetector($knowledgeBase); }); // Exception Correlation Engine $container->singleton(ExceptionCorrelationEngine::class, function($container) { return new ExceptionCorrelationEngine( cache: $container->get(Cache::class) ); }); // Exception Metrics Collector $container->singleton(ExceptionMetricsCollector::class, function($container) { return new ExceptionMetricsCollector( cache: $container->get(Cache::class) ); }); // Exception Health Checker $container->singleton(ExceptionHealthChecker::class, function($container) { return new ExceptionHealthChecker( metricsCollector: $container->get(ExceptionMetricsCollector::class), errorRateThreshold: 0.1, timeWindowSeconds: 60 ); }); // ErrorKernel mit allen Features $container->singleton(ErrorKernel::class, function($container) { return new ErrorKernel( rendererFactory: $container->get(ErrorRendererFactory::class), reporter: $container->get(Reporter::class), errorAggregator: $container->get(ErrorAggregatorInterface::class), contextProvider: $container->get(ExceptionContextProvider::class), auditLogger: $container->get(ExceptionAuditLogger::class), rateLimiter: $container->get(ExceptionRateLimiter::class), // NEU executionContext: $container->get(ExecutionContext::class), consoleOutput: $container->get(ConsoleOutput::class), isDebugMode: $container->get('config')->get('app.debug', false) ); }); ``` --- ## Best Practices ### 1. Rate Limiting konfigurieren ```php // Für Production: Strikte Limits $config = ExceptionRateLimitConfig::withLimits( maxExceptions: 5, timeWindow: Duration::fromSeconds(60) ); // Für Development: Lockerere Limits $config = ExceptionRateLimitConfig::withLimits( maxExceptions: 50, timeWindow: Duration::fromSeconds(60) ); ``` ### 2. Context Caching nutzen ```php // Context Cache nur aktivieren wenn Context-Erstellung teuer ist // (z.B. DB-Queries, externe API-Calls) if ($needsCaching) { $builder = new ExceptionContextBuilder( errorScope: $errorScope, contextCache: $contextCache ); } else { $builder = new ExceptionContextBuilder(errorScope: $errorScope); } ``` ### 3. User-Friendly Messages definieren ```php // Alle wichtigen Exceptions sollten User-Friendly Messages haben $templates = [ \App\Framework\Exception\DatabaseException::class => [ 'message' => 'Database connection failed. Please try again later.', 'title' => 'Database Error', 'help' => 'If this problem persists, please contact support.' ], \App\Framework\Exception\ValidationException::class => [ 'message' => 'Please check your input and try again.', 'title' => 'Validation Error' ] ]; ``` ### 4. Retry-Strategien wählen ```php // Für Network-Exceptions: Exponential Backoff $metadata = ExceptionMetadata::withRetry(1000) ->withRetryStrategy('exponential_backoff'); // Für Rate-Limited APIs: Linear $metadata = ExceptionMetadata::withRetry(2000) ->withRetryStrategy('linear'); // Für Polling: Fixed Delay $metadata = ExceptionMetadata::withRetry(5000) ->withRetryStrategy('fixed'); ``` ### 5. Health Checks konfigurieren ```php // Für kritische Services: Strikte Thresholds $healthChecker = new ExceptionHealthChecker( metricsCollector: $metricsCollector, errorRateThreshold: 0.05, // 5% timeWindowSeconds: 60 ); // Für weniger kritische Services: Lockerere Thresholds $healthChecker = new ExceptionHealthChecker( metricsCollector: $metricsCollector, errorRateThreshold: 0.2, // 20% timeWindowSeconds: 300 ); ``` --- ## Migration Guide ### Von altem System migrieren 1. **Rate Limiting aktivieren**: ```php // In DI Container $container->singleton(ExceptionRateLimiter::class, ...); ``` 2. **Context Caching aktivieren** (optional): ```php // Nur wenn Performance-Probleme auftreten $container->singleton(ExceptionContextCache::class, ...); ``` 3. **User-Friendly Messages hinzufügen**: ```php // Templates in config/exception_messages.php definieren ``` 4. **Health Checks registrieren**: ```php // In HealthCheckManager $healthCheckManager->register($exceptionHealthChecker); ``` --- ## Troubleshooting ### Rate Limiting blockiert zu viele Exceptions **Problem**: Rate Limiting blockiert auch wichtige Exceptions **Lösung**: Threshold erhöhen oder Time Window anpassen ```php $config = ExceptionRateLimitConfig::withLimits( maxExceptions: 20, // Erhöht timeWindow: Duration::fromSeconds(60) ); ``` ### Context Cache liefert veraltete Daten **Problem**: Context Cache enthält veraltete User/Session-Daten **Lösung**: Cache bei User/Session-Änderungen invalidieren ```php $contextCache->invalidateUser($userId); $contextCache->invalidateSession($sessionId); ``` ### Performance Tracking zeigt keine Daten **Problem**: Performance-Metriken werden nicht aufgezeichnet **Lösung**: Sicherstellen dass `ExceptionPerformanceTracker` in `ErrorKernel` integriert ist ```php // Performance-Tracking manuell starten $startData = $performanceTracker->start(); // ... exception occurs ... $metrics = $performanceTracker->end($startData, $exception, $context); ``` --- ## Weitere Ressourcen - [Error Handling Guidelines](./error-handling.md) - [Exception Architecture](../ERROR-HANDLING-UNIFIED-ARCHITECTURE.md) - [Audit Logging](./audit-logging.md)