# ErrorRenderer Verbesserungen - Template Syntax, Reflection, Optimierungen ## Problem-Analyse ### 1. Template-Syntax Inkonsistenz **Aktuell**: Templates verwenden `{variable}` Syntax **Erwartet**: Template-System verwendet PHP-Syntax `{{ $variable }}` (mit Dollar-Sign) **Betroffen**: Alle Error-Templates (`error.view.php`, `404.view.php`, `500.view.php`) ### 2. Reflection in ErrorKernel **Problem**: `createHttpResponse()` verwendet Reflection, um auf private `engine` Property zuzugreifen **Location**: `src/Framework/ExceptionHandling/ErrorKernel.php:160-163` **Lösung**: Factory-Methode für Renderer mit geändertem Debug-Mode hinzufügen ### 3. ConsoleOutput unnötig für HTTP-Context **Problem**: ConsoleOutput wird für alle Kontexte erstellt, auch wenn nicht benötigt **Location**: `src/Framework/ExceptionHandling/ExceptionHandlingInitializer.php:37-39` **Lösung**: Lazy creation nur bei CLI-Context ### 4. If-Syntax nicht kompatibel **Aktuell**: Templates verwenden `{if variable}` und `{/if}` Syntax **Erwartet**: HTML-Attribut-Syntax `
` (mit Dollar-Sign für PHP-Syntax) **Betroffen**: Alle Error-Templates mit bedingten Blöcken ### 5. Fehlerbehandlung bei Template-Rendering **Problem**: Fallback-Handling könnte robuster sein **Location**: `src/Framework/ExceptionHandling/Renderers/ResponseErrorRenderer.php:143-169` ## Lösungsvorschlag ### Phase 1: Template-Syntax korrigieren (PHP-Syntax) #### 1.1 Variable-Syntax korrigieren (PHP-Syntax mit Dollar) **Änderungen** (alle mit Dollar-Sign): - `{title}` → `{{ $title }}` - `{message}` → `{{ $message }}` - `{exceptionClass}` → `{{ $exceptionClass }}` - `{debug.file}` → `{{ $debug['file'] }}` oder `{{ $data['debug']['file'] }}` - `{debug.line}` → `{{ $debug['line'] }}` oder `{{ $data['debug']['line'] }}` - `{debug.trace}` → `{{ $debug['trace'] }}` oder `{{ $data['debug']['trace'] }}` - `{context.operation}` → `{{ $context['operation'] }}` oder `{{ $data['context']['operation'] }}` - `{context.component}` → `{{ $context['component'] }}` oder `{{ $data['context']['component'] }}` - `{context.request_id}` → `{{ $context['request_id'] }}` oder `{{ $data['context']['request_id'] }}` - `{context.occurred_at}` → `{{ $context['occurred_at'] }}` oder `{{ $data['context']['occurred_at'] }}` **Hinweis**: Da `$data` im RenderContext als Array übergeben wird, sollte Array-Syntax verwendet werden: - `{{ $data['title'] }}` - `{{ $data['debug']['file'] }}` - `{{ $data['context']['operation'] }}` **Dateien**: - `resources/views/errors/error.view.php` - `resources/views/errors/404.view.php` - `resources/views/errors/500.view.php` #### 1.2 If-Syntax auf HTML-Attribute umstellen (mit Dollar-Syntax) **Änderungen**: - `{if isDebugMode}...{/if}` → `
...
` oder `` - `{if debug}...{/if}` → `
...
` - `{if context}...{/if}` → `
...
` - `{if debug.trace}...{/if}` → `
...
` **Beispiel Transformation**: ```html {if isDebugMode}
{{message}}
{/if}
{{ $message }}
``` **Hinweis**: If-Bedingungen verwenden auch Dollar-Syntax für Variablen: `if="$isDebugMode"` **Dateien**: - `resources/views/errors/error.view.php` - `resources/views/errors/500.view.php` ### Phase 2: Reflection entfernen #### 2.1 ErrorRendererFactory erweitern **Neue Methode hinzufügen**: ```php public function createHttpRenderer(?bool $debugMode = null): ResponseErrorRenderer { $debugMode = $debugMode ?? $this->isDebugMode; return new ResponseErrorRenderer($this->engine, $debugMode); } ``` **Datei**: `src/Framework/ExceptionHandling/ErrorRendererFactory.php` #### 2.2 ErrorKernel anpassen **Reflection-Code ersetzen**: ```php // Alt (Reflection) $reflection = new \ReflectionClass($this->rendererFactory); $engineProperty = $reflection->getProperty('engine'); $engineProperty->setAccessible(true); $engine = $engineProperty->getValue($this->rendererFactory); $renderer = new ResponseErrorRenderer($engine, $debugMode); // Neu (Factory-Methode) if ($renderer instanceof ResponseErrorRenderer && $debugMode !== $this->isDebugMode) { $renderer = $this->rendererFactory->createHttpRenderer($debugMode); } ``` **Datei**: `src/Framework/ExceptionHandling/ErrorKernel.php` ### Phase 3: ConsoleOutput optimieren #### 3.1 ExceptionHandlingInitializer anpassen **Lazy Creation für ConsoleOutput**: ```php // Alt: Immer erstellen $consoleOutput = $container->has(ConsoleOutput::class) ? $container->get(ConsoleOutput::class) : new ConsoleOutput(); // Neu: Nur bei CLI-Context erstellen $consoleOutput = $executionContext->isCli() ? ($container->has(ConsoleOutput::class) ? $container->get(ConsoleOutput::class) : new ConsoleOutput()) : null; ``` **Anpassung in ErrorRendererFactory-Binding**: - Factory sollte ConsoleOutput nur bei CLI-Context benötigen - Für HTTP-Context kann `null` übergeben werden (wird nicht verwendet) **Datei**: `src/Framework/ExceptionHandling/ExceptionHandlingInitializer.php` ### Phase 4: Fehlerbehandlung verbessern #### 4.1 Template-Rendering Error Handling **Verbesserungen**: - Logging bei Template-Fehlern hinzufügen - Spezifischere Fehlermeldungen - Fallback sollte alle notwendigen Daten enthalten **Datei**: `src/Framework/ExceptionHandling/Renderers/ResponseErrorRenderer.php` #### 4.2 Fallback HTML verbessern **Sicherstellen, dass Fallback**: - Alle Template-Variablen korrekt ersetzt - HTML-Encoding korrekt anwendet - Debug-Informationen nur bei Debug-Mode zeigt **Datei**: `src/Framework/ExceptionHandling/Renderers/ResponseErrorRenderer.php` ## Implementierungs-Plan ### Schritt 1: Template-Syntax korrigieren (PHP-Syntax) 1. **error.view.php** anpassen - Variable-Syntax: `{variable}` → `{{ $variable }}` (PHP-Syntax mit Dollar) - Array-Zugriff: `{debug.file}` → `{{ $debug['file'] }}` oder `{{ $data['debug']['file'] }}` - If-Syntax: `{if}...{/if}` → HTML-Attribute `if="$variable"` (mit Dollar) - Style-Tags: Conditional Styles mit `if="$isDebugMode"` Attribut 2. **404.view.php** anpassen - Variable-Syntax korrigieren (falls vorhanden) - PHP-Syntax: `{{ $variable }}` 3. **500.view.php** anpassen - Variable-Syntax: `{variable}` → `{{ $variable }}` (PHP-Syntax mit Dollar) - Array-Zugriff für verschachtelte Daten - If-Syntax: `{if}...{/if}` → HTML-Attribute `if="$variable"` (mit Dollar) ### Schritt 2: ErrorRendererFactory erweitern 4. **createHttpRenderer() Methode hinzufügen** - Parameter: `?bool $debugMode = null` - Return: `ResponseErrorRenderer` - Verwendet interne `engine` und `isDebugMode` ### Schritt 3: Reflection entfernen 5. **ErrorKernel::createHttpResponse() refactoren** - Reflection-Code entfernen - Factory-Methode `createHttpRenderer()` verwenden - Type-Checking beibehalten ### Schritt 4: ConsoleOutput optimieren 6. **ExceptionHandlingInitializer anpassen** - ConsoleOutput nur bei CLI-Context erstellen - ErrorRendererFactory-Binding anpassen (null für HTTP-Context) 7. **ConsoleErrorRenderer anpassen** (falls nötig) - Null-Check für ConsoleOutput hinzufügen ### Schritt 5: Fehlerbehandlung verbessern 8. **ResponseErrorRenderer::renderWithTemplate() verbessern** - Logging bei Template-Fehlern - Spezifischere Exception-Typen - Bessere Fehlermeldungen 9. **Fallback HTML verbessern** - HTML-Encoding für alle Variablen - Debug-Informationen nur bei Debug-Mode - Konsistente Formatierung ### Schritt 6: Testing & Validierung 10. **Template-Syntax testen** - Alle Templates kompilieren lassen - Variable-Substitution mit PHP-Syntax testen (`{{ $variable }}`) - Array-Zugriff testen (`{{ $data['key'] }}`) - Verschachtelte Array-Zugriffe testen (`{{ $data['debug']['file'] }}`) - If-Bedingungen mit Dollar-Syntax testen (`if="$variable"`) 11. **Reflection-Entfernung testen** - createHttpResponse() mit verschiedenen Debug-Modes testen - Sicherstellen, dass keine Reflection mehr verwendet wird 12. **ConsoleOutput Optimierung testen** - CLI-Context: ConsoleOutput verfügbar - HTTP-Context: ConsoleOutput nicht erstellt ## Dateien zu ändern ### Templates: - `resources/views/errors/error.view.php` - Variable & If-Syntax (PHP-Syntax) - `resources/views/errors/404.view.php` - Variable-Syntax (PHP-Syntax, falls vorhanden) - `resources/views/errors/500.view.php` - Variable & If-Syntax (PHP-Syntax) ### PHP-Klassen: - `src/Framework/ExceptionHandling/ErrorRendererFactory.php` - createHttpRenderer() Methode - `src/Framework/ExceptionHandling/ErrorKernel.php` - Reflection entfernen - `src/Framework/ExceptionHandling/ExceptionHandlingInitializer.php` - ConsoleOutput optimieren - `src/Framework/ExceptionHandling/Renderers/ResponseErrorRenderer.php` - Fehlerbehandlung verbessern ## Wichtige Hinweise zur Template-Syntax **Variable-Syntax (PHP-Stil)**: - Einfache Variablen: `{{ $title }}` - Array-Zugriff: `{{ $data['title'] }}` - Verschachtelte Arrays: `{{ $data['debug']['file'] }}` - Object-Zugriff (falls Objekte): `{{ $object->property }}` **If-Bedingungen**: - Einfache Bedingung: `if="$isDebugMode"` - Negation: `if="!$isDebugMode"` - Array-Zugriff: `if="$debug"` - Verschachtelt: `if="$data['debug']"` **Template-Daten-Struktur**: Die Daten werden im `RenderContext` als `data` Array übergeben, daher: - `$title` entspricht `$data['title']` im Template - `$debug['file']` entspricht `$data['debug']['file']` im Template ## Vorteile ✅ **Konsistente Template-Syntax**: Verwendet PHP-Stil `{{ $variable }}` ✅ **Keine Reflection**: Sauberer Code, bessere Performance ✅ **Optimierte Ressourcennutzung**: ConsoleOutput nur bei Bedarf ✅ **HTML-Attribut-Syntax**: Kompatibel mit Framework Template-System ✅ **Robustere Fehlerbehandlung**: Besseres Logging und Fallbacks ## Risiken & Nebenwirkungen ⚠️ **Template-Syntax-Änderung**: Alle Error-Templates müssen angepasst werden ⚠️ **If-Syntax-Änderung**: Bedingte Blöcke müssen auf HTML-Attribute umgestellt werden ⚠️ **ConsoleOutput**: Null-Checks müssen bei Verwendung hinzugefügt werden ## Validierung Nach Implementierung: - [ ] Alle Templates kompilieren ohne Fehler - [ ] Variable-Substitution mit PHP-Syntax funktioniert (`{{ $variable }}`) - [ ] Array-Zugriff funktioniert (`{{ $data['key'] }}`) - [ ] Verschachtelte Array-Zugriffe funktionieren (`{{ $data['debug']['file'] }}`) - [ ] If-Bedingungen funktionieren mit HTML-Attributen und Dollar-Syntax (`if="$variable"`) - [ ] Keine Reflection mehr in ErrorKernel - [ ] ConsoleOutput nur bei CLI-Context erstellt - [ ] Fallback HTML funktioniert korrekt