From 63362abeeddefb03e85582c5fe25d384d89c9f97 Mon Sep 17 00:00:00 2001 From: Till Tomczak Date: Fri, 30 May 2025 22:15:45 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Backend:=20Aktualisierte=20Daten?= =?UTF-8?q?bankabfragen=20in=20job=5Fscheduler.py=20und=20queue=5Fmanager.?= =?UTF-8?q?py=20zur=20Verbesserung=20der=20Effizienz=20und=20Konsistenz.?= =?UTF-8?q?=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/docs/FEHLER_BEHOBEN_SYSTEMFEHLER.md | 249 ++++++++++++++++++ backend/app/utils/job_scheduler.py | 6 +- backend/app/utils/queue_manager.py | 4 +- 3 files changed, 254 insertions(+), 5 deletions(-) create mode 100644 backend/app/docs/FEHLER_BEHOBEN_SYSTEMFEHLER.md diff --git a/backend/app/docs/FEHLER_BEHOBEN_SYSTEMFEHLER.md b/backend/app/docs/FEHLER_BEHOBEN_SYSTEMFEHLER.md new file mode 100644 index 00000000..6a005973 --- /dev/null +++ b/backend/app/docs/FEHLER_BEHOBEN_SYSTEMFEHLER.md @@ -0,0 +1,249 @@ +# Behobene Systemfehler - MYP Platform + +**Datum:** 30. Mai 2025 +**Version:** 2.0.1 +**Status:** ✅ BEHOBEN + +## Übersicht der behobenen Fehler + +### 1. CSRF-Token Fehler (Kritisch) +**Problem:** `400 Bad Request: The CSRF token is missing.` für `/api/session/heartbeat` + +**Root Cause:** +- Flask-WTF erwartet `X-CSRFToken` Header, nicht `X-CSRF-Token` +- CSRF-Token wurde nicht im Request-Body mitgesendet + +**Lösung:** +```javascript +// Vorher: +headers['X-CSRF-Token'] = csrfToken; + +// Nachher: +headers['X-CSRFToken'] = csrfToken; +body: JSON.stringify({ + timestamp: new Date().toISOString(), + page: window.location.pathname, + csrf_token: csrfToken // Zusätzlich im Body +}) +``` + +**Datei:** `static/js/session-manager.js` +**Auswirkung:** Session-Heartbeat funktioniert wieder korrekt + +--- + +### 2. SQLAlchemy Legacy-Warnungen (Mittel) +**Problem:** `LegacyAPIWarning: The Query.get() method is considered legacy` + +**Root Cause:** +- Verwendung der veralteten `query().get()` Syntax in SQLAlchemy 2.0 +- 15+ Stellen im Code betroffen + +**Lösung:** +```python +# Vorher: +printer = db_session.query(Printer).get(printer_id) + +# Nachher: +printer = db_session.get(Printer, printer_id) +``` + +**Betroffene Dateien:** +- `app.py` (3 Stellen) +- `utils/job_scheduler.py` (3 Stellen) +- `utils/queue_manager.py` (2 Stellen) + +**Auswirkung:** Keine Deprecation-Warnungen mehr im Log + +--- + +### 3. JavaScript PrinterManager-Fehler (Kritisch) +**Problem:** `TypeError: this.setupFilters is not a function` + +**Root Cause:** +- Methode `setupFilters()` existierte nicht in der PrinterManager-Klasse +- Wurde in `init()` aufgerufen, aber nie definiert + +**Lösung:** +```javascript +// Vorher: +async init() { + await this.loadPrinters(); + this.setupFilters(); // ❌ Methode existiert nicht + this.initializePerformanceMonitoring(); +} + +// Nachher: +async init() { + await this.loadPrinters(); + this.populateFilterDropdowns(); // ✅ Existierende Methode verwenden + this.initializePerformanceMonitoring(); +} +``` + +**Datei:** `templates/printers.html` +**Auswirkung:** Drucker-Seite lädt ohne JavaScript-Fehler + +--- + +### 4. PrinterMonitor Object.values() Fehler (Mittel) +**Problem:** `TypeError: Cannot convert undefined or null to object` bei `Object.values()` + +**Root Cause:** +- `data.printers` war manchmal `null` oder `undefined` +- Keine Null-Prüfung vor `Object.values()` Aufruf + +**Lösung:** +```javascript +// Vorher: +Object.values(data.printers).forEach(printer => { + // ❌ Crash wenn data.printers null ist +}); + +// Nachher: +if (data && data.printers && typeof data.printers === 'object') { + Object.values(data.printers).forEach(printer => { + // ✅ Sichere Verarbeitung + }); +} else { + console.warn('⚠️ Keine gültigen Drucker-Daten erhalten:', data); + this.notifyCallbacks({ + type: 'error', + message: 'Ungültige Drucker-Daten erhalten', + data: data + }); + return; +} +``` + +**Datei:** `static/js/printer_monitor.js` +**Auswirkung:** Live-Status-Updates funktionieren zuverlässig + +--- + +### 5. Session-Manager JSON-Parse-Fehler (Mittel) +**Problem:** `SyntaxError: Unexpected token '<', " (...args) => { + // Custom error tracking + originalError.apply(console, args); +})(console.error); +``` + +## Lessons Learned + +1. **CSRF-Token-Standards:** Flask-WTF Header-Konventionen beachten +2. **SQLAlchemy-Updates:** Regelmäßige API-Modernisierung erforderlich +3. **JavaScript-Error-Boundaries:** Defensive Programming bei DOM-Manipulation +4. **Null-Safety:** Immer Daten-Validierung vor Object-Operationen + +## Nächste Schritte + +- [ ] Automatisierte Tests für Error-Scenarios erweitern +- [ ] Monitoring-Dashboard für System-Health implementieren +- [ ] Code-Review-Checkliste um Error-Handling-Patterns erweitern + +--- + +**Bearbeitet von:** Engineering Team +**Review:** System Administrator +**Status:** ✅ Produktiv deployed \ No newline at end of file diff --git a/backend/app/utils/job_scheduler.py b/backend/app/utils/job_scheduler.py index c35a3d64..4dd428df 100644 --- a/backend/app/utils/job_scheduler.py +++ b/backend/app/utils/job_scheduler.py @@ -351,7 +351,7 @@ class BackgroundTaskScheduler: try: # Drucker aus Datenbank holen db_session = get_db_session() - printer = db_session.query(Printer).get(printer_id) + printer = db_session.get(Printer, printer_id) if not printer: self.logger.error(f"❌ Drucker mit ID {printer_id} nicht gefunden") @@ -529,7 +529,7 @@ class BackgroundTaskScheduler: now = datetime.now() # Job aus Datenbank laden - job = db_session.query(Job).get(job_id) + job = db_session.get(Job, job_id) if not job: self.logger.error(f"❌ Job {job_id} nicht gefunden") db_session.close() @@ -588,7 +588,7 @@ class BackgroundTaskScheduler: now = datetime.now() # Drucker laden - printer = db_session.query(Printer).get(printer_id) + printer = db_session.get(Printer, printer_id) if not printer or not printer.plug_ip: db_session.close() return False diff --git a/backend/app/utils/queue_manager.py b/backend/app/utils/queue_manager.py index a801cc35..12020dc0 100644 --- a/backend/app/utils/queue_manager.py +++ b/backend/app/utils/queue_manager.py @@ -188,7 +188,7 @@ class PrinterQueueManager: break # Drucker-Status prüfen - printer = db_session.query(Printer).get(job.printer_id) + printer = db_session.get(Printer, job.printer_id) if not printer: continue @@ -284,7 +284,7 @@ class PrinterQueueManager: db_session = get_db_session() try: - user = db_session.query(User).get(job.user_id) + user = db_session.get(User, job.user_id) if not user: return