# Häufige Fehler und Lösungen Dieses Dokument enthält häufig auftretende Fehler und deren Lösungen für das MYP-3D-Druck-Management-System. ## Drucker-Status-Check mit 7-Sekunden-Timeout ### Implementierung (2024-12-19) **Problem:** Drucker-Status wurde nur basierend auf hardkodierten Konfigurationen bestimmt, ohne echte Netzwerk-Überprüfung. **Lösung:** Implementierung eines echten Ping-basierten Status-Checks mit 7-Sekunden-Timeout: #### Backend-Änderungen: 1. **Neue Funktionen in `app.py`:** - `check_printer_status(ip_address, timeout=7)`: Überprüft einzelnen Drucker via Ping - `check_multiple_printers_status(printers, timeout=7)`: Parallel-Check mehrerer Drucker 2. **Aktualisierte API-Endpunkte:** - `/api/printers`: Verwendet jetzt echten Status-Check - `/api/printers/status`: Spezieller Endpunkt für Status-Überprüfung 3. **Features:** - 7-Sekunden-Timeout pro Drucker - Parallel-Ausführung mit ThreadPoolExecutor - Windows- und Unix-kompatible Ping-Befehle - Detailliertes Logging der Status-Checks - Automatische Datenbank-Aktualisierung #### Frontend-Änderungen: 1. **Erweiterte Drucker-Seite (`templates/printers.html`):** - Funktionsfähiger "Aktualisieren"-Button - Loading-States mit Timeout-Information - Status-Nachrichten mit Erfolgs-/Fehler-Feedback - Zeitstempel der letzten Überprüfung 2. **Neue JavaScript-Funktionen:** - `refreshPrinters()`: Vollständiger Status-Check mit UI-Feedback - `loadPrintersWithStatusCheck()`: Erweiterte Lade-Funktion - `showStatusMessage()`: Toast-Nachrichten für Benutzer-Feedback - `formatTime()`: Relative Zeitanzeige für Status-Checks #### Benutzer-Erfahrung: - **Vor dem Update:** Drucker-Status basierte nur auf Konfiguration - **Nach dem Update:** - Echter Ping-Test mit 7-Sekunden-Timeout - Visuelles Feedback während der Überprüfung - Erfolgs-/Fehler-Nachrichten - Zeitstempel der letzten Überprüfung - Button-Deaktivierung während des Checks #### Technische Details: - **Timeout:** 7 Sekunden pro Drucker (konfigurierbar) - **Parallel-Verarbeitung:** Bis zu 10 gleichzeitige Checks - **Plattform-Unterstützung:** Windows (`ping -n 1 -w 7000`) und Unix (`ping -c 1 -W 7`) - **Fehlerbehandlung:** Graceful Fallback auf "offline" bei Timeouts oder Fehlern - **Logging:** Detaillierte Protokollierung aller Status-Checks #### Konfiguration: ```python # Timeout kann in den API-Aufrufen angepasst werden status_results = check_multiple_printers_status(printer_data, timeout=7) ``` #### Fehlerbehebung: 1. **Timeout-Probleme:** Timeout kann in der Funktion angepasst werden 2. **Netzwerk-Probleme:** Logs in `logs/printers/printers.log` prüfen 3. **Performance:** Bei vielen Druckern ThreadPool-Größe anpassen ## Job-Scheduler und Steckdosensteuerung ### Steckdose kann nicht eingeschaltet werden **Problem:** Log-Eintrag: `Fehler beim Starten von Job X: Steckdose konnte nicht eingeschaltet werden` **Mögliche Ursachen und Lösungen:** 1. **Netzwerkverbindung zu Steckdose unterbrochen** - Prüfen Sie, ob die Steckdose mit dem Netzwerk verbunden ist - Ping-Test: `ping [IP-Adresse der Steckdose]` - Steckdose neu starten (physischer Reset-Knopf) 2. **Falsche Zugangsdaten für Steckdose** - Überprüfen Sie in der Datenbank, ob die korrekten Zugangsdaten (Benutzername/Passwort) für die Steckdose hinterlegt sind - Admin-Bereich → Drucker → Steckdosenkonfiguration bearbeiten 3. **PyP110-Bibliothek veraltet** - Bibliothek aktualisieren: `pip install PyP100 --upgrade` ### Job wird nicht gestartet oder beendet **Problem:** Ein geplanter Job startet nicht oder ein laufender Job wird nicht beendet **Mögliche Ursachen und Lösungen:** 1. **Scheduler-Thread läuft nicht** - Prüfen Sie den Status des Schedulers im Admin-Bereich - Wenn nicht aktiv: Scheduler starten - Bei wiederholtem Problem: Server neu starten 2. **Datenbankprobleme** - Überprüfen Sie die Datenbank auf Konsistenz - Backup einspielen, falls notwendig ### Job-Verlängerung funktioniert nicht **Problem:** Nach dem Verlängern eines Jobs wird er trotzdem zum ursprünglichen Zeitpunkt beendet **Lösung:** 1. Prüfen Sie die Datenbankeinträge, ob die `end_at`-Zeit korrekt aktualisiert wurde 2. Prüfen Sie die Log-Dateien auf Fehler beim Aktualisieren des Jobs 3. Verlängern Sie den Job erneut mit größerem Zeitpuffer ## Sicherheitshinweise ### Sicherheitsmaßnahmen bei Stromausfällen **Wichtig:** - Bei Stromausfällen kehren die Steckdosen in ihren Standardzustand zurück (meist AUS) - Nach Wiederherstellung der Stromversorgung wird der Scheduler automatisch Jobs wieder aufnehmen - Laufende Jobs werden jedoch **nicht** automatisch fortgesetzt, um Schäden zu vermeiden - Administrator muss laufende Jobs manuell neu starten ### 5-Minuten Sicherheitspuffer Das System verwendet einen 5-Minuten Sicherheitspuffer, bevor es einen Job beendet. Dies verhindert, dass ein Druck zu früh beendet wird. Die tatsächliche Ausschaltzeit ist also immer 5 Minuten nach der im System angezeigten Endzeit. ## API-Endpunkte für Fehlerbehebung | Endpunkt | Beschreibung | |----------|--------------| | `GET /api/scheduler/status` | Status des Job-Schedulers abfragen | | `POST /api/scheduler/start` | Scheduler manuell starten (Admin) | | `POST /api/scheduler/stop` | Scheduler manuell stoppen (Admin) | | `GET /api/jobs/active` | Alle aktiven Jobs anzeigen | | `POST /api/jobs//extend` | Job-Laufzeit verlängern | | `POST /api/jobs//finish` | Job manuell beenden (Admin) | ## Benutzer-Authentifizierung ### Schema-Problem beim User-Load - "tuple index out of range" **Problem:** ``` 2025-05-31 23:08:12 - [APP] app - [WARN] WARNING - Schema-Problem beim User-Load für ID 1: tuple index out of range ``` **Ursache:** Der Flask-Login User-Loader versuchte auf Tupel-Indizes zuzugreifen, die nicht existierten, wenn die Fallback-Logik mit manueller SQL-Abfrage verwendet wurde. **Lösungen:** 1. Der User-Loader wurde mit robuster Tupel-Behandlung überarbeitet 2. Mehrstufiges Fallback-System implementiert: - Primär: ORM-Query - Sekundär: Erweiterte manuelle SQL-Abfrage - Tertiär: Notfall-User-Objekt 3. Alle Tupel-Zugriffe mit Längen-Prüfungen versehen **Behoben in:** app.py (User-Loader Funktion) ## Flask-Login Fehler ### UserMixin-Attribute fehlen **Problem:** ``` AttributeError: 'User' object has no attribute 'is_authenticated' ``` **Ursache:** Die User-Klasse erbt nicht von `UserMixin` oder implementiert nicht die erforderlichen Flask-Login Attribute. **Lösungen:** 1. Stellen Sie sicher, dass die User-Klasse von `UserMixin` erbt: ```python from flask_login import UserMixin class User(UserMixin, Base): # ... Rest der Klasse ``` 2. Implementieren Sie die erforderlichen Methoden manuell: ```python @property def is_authenticated(self): return True @property def is_active(self): return self.active @property def is_anonymous(self): return False def get_id(self): return str(self.id) ``` 3. Führen Sie die Datenbankmigration aus: ```bash python3.11 migrate_db.py ``` ### Fehlende username-Spalte **Problem:** Die Anwendung versucht auf `username` zuzugreifen, aber die Spalte existiert nicht in der Datenbank. **Lösungen:** 1. Führen Sie das Migrationsskript aus: ```bash python3.11 migrate_db.py ``` 2. Falls die Migration fehlschlägt, initialisieren Sie die Datenbank neu: ```bash python3.11 init_db.py ``` ## Datenbank-Fehler ### SQLite Database is locked **Problem:** ``` sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) database is locked ``` **Ursache:** Dieser Fehler tritt auf, wenn mehrere Prozesse gleichzeitig auf die Datenbank zugreifen. **Lösungen:** 1. Stellen Sie sicher, dass Sie alle Datenbankverbindungen mit `db_session.close()` schließen 2. Verwenden Sie `with get_db_session() as session:` um Sessions automatisch zu schließen 3. Prüfen Sie, ob der Scheduler und die Hauptanwendung gleichzeitig auf die Datenbank zugreifen ### Detached Instance Error **Problem:** ``` sqlalchemy.orm.exc.DetachedInstanceError: Instance is not bound to a Session ``` **Ursache:** Zugriff auf ein SQLAlchemy-Objekt nach dem Schließen der Session. **Lösungen:** 1. Verwenden Sie `joinedload` für eager loading: `db_session.query(Job).options(joinedload(Job.user))` 2. Konvertieren Sie Objekte zu Dictionaries, bevor Sie die Session schließen: `job_dict = job.to_dict()` 3. Verwenden Sie `session.expunge_all()` gefolgt von `session.close()`, wenn Sie Objekte weiter verwenden müssen ## Tapo Smart Plug Fehler ### Verbindungsfehler **Problem:** ``` PyP100.PyP100.P100Exception: Could not connect to device ``` **Ursache:** Smart Plug ist nicht erreichbar oder Authentifizierungsprobleme. **Lösungen:** 1. Überprüfen Sie die IP-Adresse des Smart Plugs 2. Stellen Sie sicher, dass der Smart Plug eingeschaltet und mit dem WLAN verbunden ist 3. Überprüfen Sie die Zugangsdaten in `config/settings.py` 4. Verwenden Sie einen Try-Except-Block zur Fehlerbehandlung: ```python try: p110 = PyP110.P110(ip, username, password) p110.handshake() p110.login() p110.turnOn() except Exception as e: printers_logger.error(f"Smart Plug Fehler: {str(e)}") ``` ## Flask-Anwendungsfehler ### Interner Server-Fehler (500) **Problem:** Die Anwendung gibt einen 500-Fehler zurück. **Ursache:** Verschiedene mögliche Ursachen, von Datenbank- bis hin zu Programmierfehlern. **Lösungen:** 1. Überprüfen Sie die Logs unter `logs/app/app.log` und `logs/errors/errors.log` 2. Starten Sie die Anwendung im Debug-Modus: `FLASK_DEBUG=True python3.11 app.py` 3. Implementieren Sie bessere Fehlerbehandlung mit Try-Except-Blöcken ### Authentifizierungsfehler **Problem:** Benutzer können sich nicht anmelden oder erhalten unbefugte Zugriffsfehler. **Ursachen:** - Ungültige Anmeldedaten - Session-Probleme - Cookie-Probleme **Lösungen:** 1. Überprüfen Sie die Logs unter `logs/auth/auth.log` 2. Setzen Sie das Passwort zurück mit: ```python from models import User, get_db_session db_session = get_db_session() user = db_session.query(User).filter(User.username == "admin").first() user.set_password("neues_passwort") db_session.commit() db_session.close() ``` 3. Löschen Sie Browser-Cookies und -Cache ## CSS und Frontend-Fehler ### Tailwind-Stile werden nicht angewendet **Problem:** Die Tailwind-Klassen haben keine Wirkung auf das Styling. **Lösungen:** 1. Stellen Sie sicher, dass die generierte CSS-Datei korrekt eingebunden ist: ```html ``` 2. Bauen Sie die CSS-Datei neu: `npm run build:css` 3. Überprüfen Sie in der Browser-Konsole, ob Fehler beim Laden der CSS-Datei auftreten ### Dark Mode funktioniert nicht **Problem:** Die Dark-Mode-Stile werden nicht angewendet. **Lösungen:** 1. Stellen Sie sicher, dass das HTML-Element die entsprechende Klasse hat: ```html ``` 2. Überprüfen Sie, ob die Tailwind-Konfiguration Dark Mode aktiviert hat: ```js // tailwind.config.js module.exports = { darkMode: 'class', // ... } ``` ## Scheduler-Fehler ### Scheduler führt keine Jobs aus **Problem:** Der Scheduler schaltet Drucker nicht ein/aus wie erwartet. **Ursachen:** - Scheduler ist nicht gestartet - Fehler bei der Tapo-Verbindung - Fehler in der Scheduler-Logik **Lösungen:** 1. Überprüfen Sie die Logs unter `logs/scheduler/scheduler.log` 2. Stellen Sie sicher, dass `SCHEDULER_ENABLED = True` in `config/settings.py` gesetzt ist 3. Starten Sie die Anwendung neu ## Performance-Probleme ### Langsame Ladezeiten **Problem:** Die Anwendung lädt langsam oder reagiert träge. **Lösungen:** 1. Optimieren Sie Datenbankabfragen mit geeigneten Indizes 2. Reduzieren Sie die Anzahl der Datenbankabfragen durch Eager Loading 3. Implementieren Sie Caching für häufig abgerufene Daten 4. Überprüfen Sie die Logfiles auf übermäßige Logging-Aktivitäten ## Content Security Policy (CSP) Fehler ### Script-src-elem 'none' Fehler **Problem:** ``` Refused to load the script because it violates the following Content Security Policy directive: "script-src-elem 'none'". ``` **Ursache:** Die Content Security Policy ist zu restriktiv eingestellt und blockiert das Laden von Skripten. **Lösungen:** 1. Überprüfen Sie die CSP-Konfiguration in `config/security.py`: ```python 'Content-Security-Policy': ( "default-src 'self'; " "script-src 'self' 'unsafe-eval' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; " "script-src-elem 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; " # ... weitere Regeln ) ``` 2. Stellen Sie sicher, dass die CSP in der `after_request`-Funktion richtig angewendet wird: ```python @app.after_request def add_security_headers(response): from config.security import get_security_headers security_headers = get_security_headers() for header, value in security_headers.items(): response.headers[header] = value # CSP-Report-Only Header entfernen if 'Content-Security-Policy-Report-Only' in response.headers: del response.headers['Content-Security-Policy-Report-Only'] return response ``` 3. Vermeiden Sie mehrere konkurrierende Service Worker Registrierungen, die CSP-Konflikte verursachen können. ### Inline Script Fehler **Problem:** ``` Refused to execute inline script because it violates the following Content Security Policy directive: "script-src-elem 'none'" ``` **Lösungen:** 1. Fügen Sie 'unsafe-inline' zur script-src Direktive hinzu 2. Alternativ fügen Sie einen Hash oder Nonce für das Inline-Skript hinzu: ```html ``` und in der CSP: ``` script-src 'nonce-{{ csp_nonce }}'; ``` ### Service Worker Registration Fehler **Problem:** ``` Refused to create a worker from 'URL' because it violates the following Content Security Policy directive: "script-src 'none'" ``` **Lösungen:** 1. Stellen Sie sicher, dass die `worker-src` Direktive korrekt konfiguriert ist: ``` worker-src 'self' blob:; ``` 2. Erstellen Sie die erforderlichen Service Worker Dateien im richtigen Verzeichnis 3. Verwenden Sie einen einheitlichen Ansatz zur Service Worker Registrierung, vorzugsweise im offline-app.js: ```javascript if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/static/js/sw.js') .then(function(registration) { console.log('Service Worker registriert:', registration.scope); }) .catch(function(error) { console.log('Service Worker Registration fehlgeschlagen:', error); // Fallback }); }); } ``` ### Icon 404 Fehler **Problem:** ``` Failed to load resource: the server responded with a status of 404 (NOT FOUND) Error while trying to use the following icon from the Manifest: URL (Download error or resource isn't a valid image) ``` **Lösungen:** 1. Erstellen Sie die fehlenden Icon-Dateien im Verzeichnis `static/icons/` 2. Aktualisieren Sie das Web App Manifest, um nur verfügbare Icons zu referenzieren: ```json "icons": [ { "src": "/static/icons/mercedes-logo.svg", "sizes": "192x192", "type": "image/svg+xml" } ] ``` 3. Verwenden Sie Tools wie Lighthouse, um fehlende PWA-Ressourcen zu identifizieren ## JavaScript-Referenzfehler ### Problem: Nicht definierte Funktionen in admin-panel.js Fehlermeldungen wie "Uncaught ReferenceError: loadPrinters is not defined" können auftreten, wenn Funktionen in der JavaScript-Datei verwendet, aber nicht definiert werden. **Lösung:** - Implementiere die fehlenden Funktionen (loadPrinters, loadSchedulerStatus, loadSystemStats, loadLogs, loadUsers, etc.) - Stelle sicher, dass alle aufgerufenen Funktionen im richtigen Scope definiert sind - Überprüfe die Reihenfolge der Funktionsdefinitionen und -aufrufe ### Problem: Funktionen in anderen Dateien werden nicht gefunden Fehler wie "Uncaught ReferenceError: refreshJobs is not defined" in jobs.html oder "exportStats is not defined" in stats.html. **Lösung:** - Stelle sicher, dass die Funktionen in der jeweiligen HTML-Datei oder in einer eingebundenen JavaScript-Datei definiert sind - Überprüfe, ob die JavaScript-Dateien korrekt in der HTML-Datei eingebunden sind - Nutze konsistente Namenskonventionen für Funktionen ## Service Worker Fehler ### Problem: Cache-API kann mit chrome-extension URLs nicht umgehen Fehler: "Uncaught (in promise) TypeError: Failed to execute 'put' on 'Cache': Request scheme 'chrome-extension' is unsupported" **Lösung:** - Überprüfe die URL-Protokolle bevor du Cache-Operationen durchführst - Füge eine spezielle Behandlung für chrome-extension-Protokolle hinzu - Verwende try-catch-Blöcke, um Fehler bei der Cache-Handhabung abzufangen ```javascript if (url.protocol === 'chrome-extension:') { // Spezielle Behandlung für chrome-extension URLs try { return await fetch(request); } catch (error) { console.error('Failed to fetch from chrome-extension:', error); return new Response(JSON.stringify({ error: 'Fehler beim Zugriff auf chrome-extension', offline: true }), { status: 400, headers: { 'Content-Type': 'application/json' } }); } } ``` ## API-Endpunkt Fehler ### Problem: API-Ressourcen werden nicht gefunden (404) Fehlermeldungen wie "Failed to load resource: the server responded with a status of 404 (NOT FOUND)" **Lösung:** - Überprüfe die API-Routen im Backend - Stelle sicher, dass die API-Endpunkte korrekt implementiert sind - Überprüfe die Anfrage-URLs in den Frontend-Skripten - Füge Fehlerbehandlung für fehlende Ressourcen hinzu ## Frontend-Rendering Fehler ### Problem: Fehler beim Laden der Admin-Statistiken "Error loading admin: admin-panel.js:484 Fehler beim Laden der Admin-Statistiken" **Lösung:** - Implementiere ordnungsgemäße Fehlerbehandlung in API-Anfragen - Zeige benutzerfreundliche Fehlermeldungen an - Füge Fallback-Werte für fehlende Daten hinzu ```javascript try { const response = await fetch('/api/admin/stats'); if (!response.ok) { throw new Error('Fehler beim Laden der Admin-Statistiken'); } const data = await response.json(); // Daten verarbeiten } catch (error) { console.error('Error loading admin stats:', error); showNotification('Fehler beim Laden der Admin-Statistiken', 'error'); } ``` ## Icon/Ressourcen Fehler ### Problem: Icon-Dateien werden nicht gefunden "Error while trying to use the following icon from the Manifest: http://127.0.0.1:5000/static/icons/icon-144x144.png" **Lösung:** - Überprüfe, ob die Icon-Dateien im richtigen Verzeichnis vorhanden sind - Stelle sicher, dass die Pfade in der Manifest-Datei korrekt sind - Füge Fallback-Icons für den Fall hinzu, dass die primären Icons nicht geladen werden können ## Allgemeine Fehlerbehebung 1. **Browser-Konsole prüfen**: Die meisten JavaScript-Fehler werden in der Browser-Konsole angezeigt (F12 oder Rechtsklick -> Untersuchen -> Konsole) 2. **Netzwerk-Tab prüfen**: Im Netzwerk-Tab des Browsers können fehlgeschlagene API-Anfragen identifiziert werden 3. **Codestruktur überprüfen**: Stelle sicher, dass alle Funktionen in der richtigen Reihenfolge definiert werden 4. **Fehlerbehandlung verbessern**: Implementiere try-catch-Blöcke für alle asynchronen Funktionen 5. **Browser-Cache leeren**: Manchmal können Probleme durch veraltete gecachte Dateien verursacht werden ## 404 Fehler (Seite nicht gefunden) ### Fehlende Routen oder API-Endpunkte **Problem:** Die Anwendung zeigt 404-Fehler für bestimmte Routen wie `/privacy`, `/terms`, `/my/jobs`, `/api/user/export` oder `/api/user/profile`. **Ursachen:** - Die Route wurde nicht korrekt in `app.py` oder dem entsprechenden Blueprint registriert - Bei API-Endpunkten: Die alte API-Route wurde verwendet, aber die Anwendung nutzt jetzt eine neue Route - Möglicherweise wurden die Templates erstellt, aber die Routen dafür fehlen **Lösungen:** 1. **Für öffentliche Seiten** (`/privacy`, `/terms`): - Überprüfen Sie, ob die Routen in `app.py` definiert sind - Stellen Sie sicher, dass der `@login_required` Decorator entfernt wurde, falls diese Seiten öffentlich sein sollen - Prüfen Sie, ob die entsprechenden Template-Dateien unter `templates/` existieren 2. **Für Benutzer-spezifische Seiten** (`/my/jobs`): - Fügen Sie eine Route hinzu, die zur Jobs-Seite mit vorgefiltertem Benutzer-Parameter weiterleitet 3. **Für API-Weiterleitungen** (`/api/user/export`, `/api/user/profile`): - Erstellen Sie Weiterleitungsrouten, die zu den neuen Blueprint-Routen führen - Beispiel: `/api/user/export` sollte zu `/user/export` weiterleiten 4. **Debugging von Routen:** - Mit `flask routes` können Sie alle registrierten Routen auflisten - Überprüfen Sie die Log-Dateien auf fehlgeschlagene Routenzugriffe - Im Debug-Modus starten: `FLASK_DEBUG=True python3.11 app.py` 5. **Blueprint-Registrierung prüfen:** - Stellen Sie sicher, dass alle Blueprints korrekt in `app.py` registriert sind: ```python from blueprints.user import user_bp app.register_blueprint(user_bp) ``` --- Dieses Dokument wird kontinuierlich aktualisiert, wenn neue Fehler auftreten und Lösungen gefunden werden.