# ErrorRenderer Refactoring - Unified Interface & Template Integration ## Problem-Analyse ### Aktuelle Probleme 1. **Interface-Hierarchie ist nicht optimal**: - `ErrorRenderer` (base) → `HttpErrorRenderer` extends → `CliErrorRenderer` extends - Verschiedene Interfaces mit unterschiedlichen Methoden - Factory muss spezifische Interfaces prüfen (`HttpErrorRenderer`, `CliErrorRenderer`) 2. **HTTP Renderer verwendet kein Template System**: - Hardcoded HTML-Strings in `ResponseErrorRenderer` - Sollte `Engine` und `RenderContext` aus Template-System verwenden - Template-basierte Error-Pages wären besser wartbar 3. **HttpEmitter Kontext**: - **Klarstellung**: HTML-Rendering sollte nur im Middleware-Kontext passieren - Renderer erstellt nur `HttpResponse`, Emitter bleibt in Application/Middleware - Außerhalb Middleware (z.B. Bootstrap): Fallback auf einfaches HTML ## Lösungsvorschlag ### 1. Unified ErrorRenderer Interface (OHNE Hierarchie) **Neue Struktur**: ```php interface ErrorRenderer { /** * Check if this renderer can handle the exception */ public function canRender(\Throwable $exception): bool; /** * Render exception to appropriate output format * * @return mixed HttpResponse for HTTP context, void for CLI context */ public function render( \Throwable $exception, ?ExceptionContextProvider $contextProvider = null ): mixed; } ``` **Alle Renderer implementieren das gleiche Interface**: - `ResponseErrorRenderer` → `HttpResponse` zurückgeben - `ConsoleErrorRenderer` → `void` (gibt direkt auf Console aus) ### 2. HTTP Renderer mit Template System **ResponseErrorRenderer sollte**: - Template System (`Engine`, `RenderContext`) für HTML-Rendering verwenden - Error-Templates mit `.view.php` Endung (auto-discovered) - JSON-Responses direkt erstellen (bleibt gleich) - Template-Namen: `errors/error`, `errors/404`, `errors/500` **Template-Struktur** (mit `.view.php` Endung): ``` resources/views/errors/ ├── error.view.php # Basis Error-Template ├── 404.view.php # 404-spezifisches Template ├── 500.view.php # 500-spezifisches Template └── debug.view.php # Debug-Informationen (nur wenn debug=true) ``` **Wichtig**: Templates werden auto-discovered über Discovery-System ### 3. HttpEmitter & Rendering-Kontext **Architektur**: ``` Exception im Middleware-Stack → ExceptionHandlingMiddleware fängt Exception → ErrorKernel->createHttpResponse() → ResponseErrorRenderer.render() (Template-System für HTML) → HttpResponse zurückgegeben → ResponseEmitter emittet Response (in Application) Exception außerhalb Middleware (z.B. Bootstrap) → GlobalExceptionHandler->handle() → ErrorKernel->handle() (nur Logging, kein Response) → Oder: Fallback HTML direkt (ohne Template-System) ``` **Prinzip**: - Renderer erstellt nur `HttpResponse` - kein direkter HttpEmitter-Aufruf - HTML-Rendering mit Templates nur im Middleware-Kontext - Außerhalb Middleware: Fallback auf einfache HTML-Strings ### 4. Entfernung der Interface-Hierarchie **Zu entfernen**: - `HttpErrorRenderer` Interface - `CliErrorRenderer` Interface **Zu behalten/ändern**: - `ErrorRenderer` Interface (einheitlich) - `ResponseErrorRenderer` → implementiert `ErrorRenderer` - `ConsoleErrorRenderer` → implementiert `ErrorRenderer` ### 5. Factory-Anpassung **ErrorRendererFactory**: - Nutzt nur noch `ErrorRenderer` Interface - Keine spezifischen Interface-Prüfungen mehr nötig - Einfacher und konsistenter ## Implementierungs-Plan ### Phase 1: Interface-Vereinheitlichung 1. **ErrorRenderer Interface refactoren** - `render()` Methode mit `mixed` Return-Type - `canRender()` bleibt gleich 2. **ResponseErrorRenderer anpassen** - Implementiert nur noch `ErrorRenderer` - `render()` gibt `HttpResponse` zurück - `createResponse()` entfernen (wird zu `render()`) 3. **ConsoleErrorRenderer anpassen** - Implementiert nur noch `ErrorRenderer` - `render()` gibt `void` zurück - `renderToConsole()` entfernen (wird zu `render()`) 4. **HttpErrorRenderer & CliErrorRenderer Interfaces löschen** ### Phase 2: Template System Integration 5. **Error Templates erstellen** (mit `.view.php` Endung) - `resources/views/errors/error.view.php` - Basis Error-Template - `resources/views/errors/404.view.php` - 404 Template - `resources/views/errors/500.view.php` - 500 Template - `resources/views/errors/debug.view.php` - Debug Template (optional) 6. **ResponseErrorRenderer mit Template System** - `Engine` über DI injizieren - `RenderContext` für Template-Rendering erstellen - HTML-Rendering über Templates (auto-discovered) - JSON-Responses bleiben direkt (kein Template nötig) - Fallback auf einfaches HTML wenn Template nicht gefunden 7. **Template-Discovery Integration** - Templates werden automatisch über Discovery-System gefunden - Template-Namen: `errors/error`, `errors/404`, etc. - Template-Loader findet Templates automatisch ### Phase 3: Factory & Integration 8. **ErrorRendererFactory vereinfachen** - Nur noch `ErrorRenderer` Interface verwenden - Spezifische Methoden (`getHttpRenderer()`, `getCliRenderer()`) entfernen 9. **ErrorKernel anpassen** - Nutzt einheitliches `ErrorRenderer` Interface - `createHttpResponse()` verwendet `render()` Methode 10. **Tests aktualisieren** - Alle Renderer-Tests anpassen - Template-System-Tests hinzufügen ## Dateien zu ändern ### Zu ändern: - `src/Framework/ExceptionHandling/ErrorRenderer.php` - Interface vereinheitlichen - `src/Framework/ExceptionHandling/Renderers/ResponseErrorRenderer.php` - Template System integrieren - `src/Framework/ExceptionHandling/Renderers/ConsoleErrorRenderer.php` - Interface anpassen - `src/Framework/ExceptionHandling/ErrorRendererFactory.php` - Vereinfachen - `src/Framework/ExceptionHandling/ErrorKernel.php` - Renderer-Aufruf anpassen ### Zu löschen: - `src/Framework/ExceptionHandling/HttpErrorRenderer.php` - Interface entfernen - `src/Framework/ExceptionHandling/CliErrorRenderer.php` - Interface entfernen ### Neu zu erstellen: - `resources/views/errors/error.view.php` - Basis Error-Template (auto-discovered) - `resources/views/errors/404.view.php` - 404 Template - `resources/views/errors/500.view.php` - 500 Template - `resources/views/errors/debug.view.php` - Debug Template (optional) ## Vorteile ✅ **Einheitliches Interface**: Alle Renderer verwenden das gleiche Interface ✅ **Keine Interface-Hierarchie**: Einfacher und klarer ✅ **Template-basierte Error-Pages**: Wartbarer und konsistenter ✅ **Framework-Integration**: Nutzt vorhandenes Template-System ✅ **Bessere Testbarkeit**: Einheitliche Interface-Struktur ✅ **Auto-Discovery**: Templates werden automatisch gefunden ## Zusammenfassung 1. ✅ Templates haben `.view.php` Endung und werden auto-discovered 2. ✅ HTML-Rendering nur im Middleware-Kontext (mit Templates) 3. ✅ Außerhalb Middleware: Fallback auf einfaches HTML 4. ✅ Renderer erstellt nur Response, Emitter bleibt in Application 5. ✅ Einheitliches `ErrorRenderer` Interface ohne Hierarchie