Files
michaelschiemer/docs/ERROR-RENDERER-REFACTORING-PLAN.md
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

200 lines
7.1 KiB
Markdown

# 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