375 lines
9.9 KiB
Markdown
375 lines
9.9 KiB
Markdown
# MYP V2 - Häufige Fehler und Lösungen
|
|
|
|
## Übersicht
|
|
Diese Datei dokumentiert häufige Fehler, die während der Entwicklung und dem Betrieb von MYP V2 auftreten können, sowie deren Lösungen.
|
|
|
|
## 🔧 Setup und Installation
|
|
|
|
### Fehler: ModuleNotFoundError für PyP100
|
|
**Symptom**: `ModuleNotFoundError: No module named 'PyP100'`
|
|
|
|
**Ursache**: PyP100-Bibliothek ist nicht installiert
|
|
|
|
**Lösung**:
|
|
```bash
|
|
pip3.11 install PyP100
|
|
```
|
|
|
|
### Fehler: Datenbankverbindung fehlgeschlagen
|
|
**Symptom**: `sqlite3.OperationalError: unable to open database file`
|
|
|
|
**Ursache**:
|
|
- Fehlende Schreibberechtigung im Datenbank-Verzeichnis
|
|
- Verzeichnis existiert nicht
|
|
|
|
**Lösung**:
|
|
```bash
|
|
# Verzeichnis erstellen
|
|
mkdir -p /path/to/database/directory
|
|
# Berechtigungen setzen
|
|
chmod 755 /path/to/database/directory
|
|
```
|
|
|
|
### Fehler: Log-Verzeichnis nicht gefunden
|
|
**Symptom**: `FileNotFoundError: [Errno 2] No such file or directory: 'logs/app/app.log'`
|
|
|
|
**Ursache**: Log-Verzeichnisse wurden nicht erstellt
|
|
|
|
**Lösung**: Die `ensure_log_directories()` Funktion in `logging_config.py` wird automatisch aufgerufen
|
|
|
|
## 🔐 Authentifizierung und Autorisierung
|
|
|
|
### Fehler: Session-Timeout zu kurz
|
|
**Symptom**: Benutzer werden zu häufig abgemeldet
|
|
|
|
**Ursache**: `SESSION_LIFETIME` in `settings.py` zu niedrig eingestellt
|
|
|
|
**Lösung**:
|
|
```python
|
|
# In config/settings.py
|
|
SESSION_LIFETIME = timedelta(days=7) # Oder gewünschte Dauer
|
|
```
|
|
|
|
### Fehler: Admin-Rechte nicht erkannt
|
|
**Symptom**: `AttributeError: 'AnonymousUserMixin' object has no attribute 'is_admin'`
|
|
|
|
**Ursache**: Benutzer ist nicht angemeldet oder UserMixin-Objekt falsch erstellt
|
|
|
|
**Lösung**: Prüfung in Decorators verbessern:
|
|
```python
|
|
if not current_user.is_authenticated or not hasattr(current_user, 'is_admin') or not current_user.is_admin:
|
|
return jsonify({"error": "Keine Berechtigung"}), 403
|
|
```
|
|
|
|
### Fehler: Passwort-Hash-Fehler
|
|
**Symptom**: `ValueError: Invalid salt`
|
|
|
|
**Ursache**: Inkonsistente Passwort-Hash-Methoden
|
|
|
|
**Lösung**: Einheitliche Verwendung von `werkzeug.security`:
|
|
```python
|
|
from werkzeug.security import generate_password_hash, check_password_hash
|
|
```
|
|
|
|
## 🖨️ Drucker und Smart Plug-Steuerung
|
|
|
|
### Fehler: Tapo-Verbindung fehlgeschlagen
|
|
**Symptom**: `Exception: Failed to establish a new connection`
|
|
|
|
**Ursache**:
|
|
- Falsche IP-Adresse
|
|
- Netzwerkprobleme
|
|
- Falsche Credentials
|
|
|
|
**Lösung**:
|
|
1. IP-Adresse in `PRINTERS` Konfiguration prüfen
|
|
2. Netzwerkverbindung testen: `ping <ip-address>`
|
|
3. Credentials in `settings.py` überprüfen
|
|
|
|
### Fehler: Plug-Status kann nicht abgerufen werden
|
|
**Symptom**: `KeyError: 'device_on'`
|
|
|
|
**Ursache**: Unerwartete API-Antwort von Tapo-Gerät
|
|
|
|
**Lösung**: Defensive Programmierung:
|
|
```python
|
|
plug_state = plug_info.get("device_on", False)
|
|
power_consumption = plug_info.get("current_power", 0)
|
|
```
|
|
|
|
### Fehler: Drucker nicht in Konfiguration gefunden
|
|
**Symptom**: `Drucker nicht in Konfiguration gefunden`
|
|
|
|
**Ursache**: Drucker-Name stimmt nicht mit `PRINTERS` Dictionary überein
|
|
|
|
**Lösung**:
|
|
1. Verfügbare Drucker in `settings.py` prüfen
|
|
2. Exakte Schreibweise verwenden
|
|
3. Neue Drucker zur Konfiguration hinzufügen
|
|
|
|
## 📅 Job-Management
|
|
|
|
### Fehler: Überlappende Jobs nicht erkannt
|
|
**Symptom**: Mehrere Jobs laufen gleichzeitig auf einem Drucker
|
|
|
|
**Ursache**: Fehlerhafte Überlappungsprüfung in der Datenbank-Abfrage
|
|
|
|
**Lösung**: Korrekte SQL-Abfrage verwenden:
|
|
```python
|
|
overlapping_jobs = db_session.query(Job).filter(
|
|
Job.printer_id == printer_id,
|
|
Job.status.in_(["scheduled", "active"]),
|
|
((Job.start_time <= start_time) & (Job.end_time > start_time)) |
|
|
((Job.start_time < end_time) & (Job.end_time >= end_time)) |
|
|
((Job.start_time >= start_time) & (Job.end_time <= end_time))
|
|
).count()
|
|
```
|
|
|
|
### Fehler: Datumsformat-Parsing fehlgeschlagen
|
|
**Symptom**: `ValueError: time data does not match format`
|
|
|
|
**Ursache**: Inkonsistente Datumsformate zwischen Frontend und Backend
|
|
|
|
**Lösung**: ISO-Format verwenden:
|
|
```python
|
|
start_time = datetime.fromisoformat(data["start_time"].replace("Z", "+00:00"))
|
|
```
|
|
|
|
### Fehler: Job-Status nicht aktualisiert
|
|
**Symptom**: Jobs bleiben im "scheduled" Status obwohl sie laufen sollten
|
|
|
|
**Ursache**:
|
|
- Scheduler läuft nicht
|
|
- Fehler im Job-Monitor
|
|
|
|
**Lösung**:
|
|
1. Scheduler-Status prüfen: `GET /api/scheduler/status`
|
|
2. Logs überprüfen: `logs/scheduler/scheduler.log`
|
|
3. Scheduler neu starten: `POST /api/scheduler/start`
|
|
|
|
## 🗄️ Datenbank-Probleme
|
|
|
|
### Fehler: Foreign Key Constraint
|
|
**Symptom**: `sqlite3.IntegrityError: FOREIGN KEY constraint failed`
|
|
|
|
**Ursache**: Versuch, referenzierte Datensätze zu löschen
|
|
|
|
**Lösung**: Abhängigkeiten vor dem Löschen prüfen:
|
|
```python
|
|
# Vor dem Löschen eines Druckers
|
|
active_jobs = db_session.query(Job).filter(
|
|
Job.printer_id == printer_id,
|
|
Job.status.in_(["scheduled", "active"])
|
|
).count()
|
|
|
|
if active_jobs > 0:
|
|
return jsonify({"error": "Es existieren aktive Jobs für diesen Drucker"}), 400
|
|
```
|
|
|
|
### Fehler: Datenbank-Session nicht geschlossen
|
|
**Symptom**: `ResourceWarning: unclosed <sqlite3.Connection>`
|
|
|
|
**Ursache**: Vergessene `db_session.close()` Aufrufe
|
|
|
|
**Lösung**: Immer `try/finally` verwenden:
|
|
```python
|
|
db_session = get_db_session()
|
|
try:
|
|
# Datenbankoperationen
|
|
pass
|
|
finally:
|
|
db_session.close()
|
|
```
|
|
|
|
### Fehler: Unique Constraint Violation
|
|
**Symptom**: `sqlite3.IntegrityError: UNIQUE constraint failed`
|
|
|
|
**Ursache**: Versuch, doppelte Einträge zu erstellen
|
|
|
|
**Lösung**: Vor dem Einfügen prüfen:
|
|
```python
|
|
existing = db_session.query(User).filter(User.email == email).first()
|
|
if existing:
|
|
return jsonify({"error": "E-Mail bereits registriert"}), 400
|
|
```
|
|
|
|
## 📊 Logging und Monitoring
|
|
|
|
### Fehler: Log-Rotation funktioniert nicht
|
|
**Symptom**: Log-Dateien werden sehr groß
|
|
|
|
**Ursache**: `RotatingFileHandler` nicht korrekt konfiguriert
|
|
|
|
**Lösung**: Konfiguration in `logging_config.py` prüfen:
|
|
```python
|
|
handler = RotatingFileHandler(
|
|
log_file,
|
|
maxBytes=10*1024*1024, # 10MB
|
|
backupCount=5
|
|
)
|
|
```
|
|
|
|
### Fehler: Logger schreibt nicht in Datei
|
|
**Symptom**: Keine Log-Einträge in den Dateien
|
|
|
|
**Ursache**:
|
|
- Log-Level zu hoch eingestellt
|
|
- Handler nicht korrekt hinzugefügt
|
|
|
|
**Lösung**:
|
|
1. Log-Level prüfen: `logger.setLevel(logging.INFO)`
|
|
2. Handler hinzufügen: `logger.addHandler(handler)`
|
|
|
|
### Fehler: Doppelte Log-Einträge
|
|
**Symptom**: Jeder Log-Eintrag erscheint mehrfach
|
|
|
|
**Ursache**: Logger-Vererbung oder mehrfache Handler-Registrierung
|
|
|
|
**Lösung**: `propagate` deaktivieren:
|
|
```python
|
|
logger.propagate = False
|
|
```
|
|
|
|
## 🔄 Scheduler-Probleme
|
|
|
|
### Fehler: Scheduler startet nicht
|
|
**Symptom**: `scheduler.is_running()` gibt `False` zurück
|
|
|
|
**Ursache**:
|
|
- `SCHEDULER_ENABLED = False` in Konfiguration
|
|
- Fehler beim Task-Registrieren
|
|
|
|
**Lösung**:
|
|
1. Konfiguration prüfen: `SCHEDULER_ENABLED = True`
|
|
2. Task-Registrierung überprüfen
|
|
3. Logs analysieren: `logs/scheduler/scheduler.log`
|
|
|
|
### Fehler: Tasks werden nicht ausgeführt
|
|
**Symptom**: Job-Monitor läuft nicht automatisch
|
|
|
|
**Ursache**:
|
|
- Task nicht korrekt registriert
|
|
- Fehler in der Task-Funktion
|
|
|
|
**Lösung**:
|
|
1. Task-Status prüfen: `scheduler.get_task_info()`
|
|
2. Task-Funktion auf Fehler prüfen
|
|
3. Interval-Einstellungen überprüfen
|
|
|
|
### Fehler: Scheduler-Thread blockiert
|
|
**Symptom**: Anwendung reagiert nicht mehr
|
|
|
|
**Ursache**: Endlosschleife oder blockierende Operation in Task
|
|
|
|
**Lösung**:
|
|
1. Timeout für externe Operationen setzen
|
|
2. Exception-Handling in Tasks verbessern
|
|
3. Scheduler neu starten
|
|
|
|
## 🌐 API und HTTP-Probleme
|
|
|
|
### Fehler: CORS-Probleme
|
|
**Symptom**: `Access-Control-Allow-Origin` Fehler im Browser
|
|
|
|
**Ursache**: Frontend und Backend auf verschiedenen Ports
|
|
|
|
**Lösung**: Flask-CORS installieren und konfigurieren:
|
|
```python
|
|
from flask_cors import CORS
|
|
CORS(app)
|
|
```
|
|
|
|
### Fehler: 500 Internal Server Error
|
|
**Symptom**: Unspezifische Server-Fehler
|
|
|
|
**Ursache**: Unbehandelte Exceptions
|
|
|
|
**Lösung**:
|
|
1. Debug-Modus aktivieren: `FLASK_DEBUG = True`
|
|
2. Logs überprüfen
|
|
3. Try-Catch-Blöcke erweitern
|
|
|
|
### Fehler: JSON-Serialisierung fehlgeschlagen
|
|
**Symptom**: `TypeError: Object of type datetime is not JSON serializable`
|
|
|
|
**Ursache**: Datetime-Objekte in JSON-Response
|
|
|
|
**Lösung**: `.isoformat()` verwenden:
|
|
```python
|
|
"created_at": obj.created_at.isoformat() if obj.created_at else None
|
|
```
|
|
|
|
## 🔧 Performance-Probleme
|
|
|
|
### Fehler: Langsame Datenbankabfragen
|
|
**Symptom**: API-Responses dauern sehr lange
|
|
|
|
**Ursache**: Fehlende Indizes oder ineffiziente Abfragen
|
|
|
|
**Lösung**:
|
|
1. Indizes auf häufig abgefragte Spalten erstellen
|
|
2. Query-Optimierung mit `EXPLAIN QUERY PLAN`
|
|
3. Eager Loading für Beziehungen verwenden
|
|
|
|
### Fehler: Speicher-Leaks
|
|
**Symptom**: Speicherverbrauch steigt kontinuierlich
|
|
|
|
**Ursache**:
|
|
- Nicht geschlossene Datenbankverbindungen
|
|
- Zirkuläre Referenzen
|
|
|
|
**Lösung**:
|
|
1. Connection-Pooling implementieren
|
|
2. Regelmäßige Garbage Collection
|
|
3. Memory-Profiling mit `memory_profiler`
|
|
|
|
## 🛠️ Entwicklungsumgebung
|
|
|
|
### Fehler: Import-Fehler in Tests
|
|
**Symptom**: `ModuleNotFoundError` beim Ausführen von Tests
|
|
|
|
**Ursache**: PYTHONPATH nicht korrekt gesetzt
|
|
|
|
**Lösung**:
|
|
```bash
|
|
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
|
|
python3.11 -m pytest
|
|
```
|
|
|
|
### Fehler: Konfigurationsdateien nicht gefunden
|
|
**Symptom**: `FileNotFoundError` für `settings.py`
|
|
|
|
**Ursache**: Arbeitsverzeichnis stimmt nicht
|
|
|
|
**Lösung**: Relative Pfade verwenden oder Arbeitsverzeichnis setzen:
|
|
```bash
|
|
cd /path/to/MYP_V2
|
|
python3.11 app/app.py
|
|
```
|
|
|
|
## 📋 Checkliste für Fehlerbehebung
|
|
|
|
### Vor jeder Änderung:
|
|
1. [ ] Aktuelle Logs überprüfen
|
|
2. [ ] Datenbank-Backup erstellen
|
|
3. [ ] Konfiguration validieren
|
|
4. [ ] Tests ausführen (falls vorhanden)
|
|
|
|
### Nach jeder Änderung:
|
|
1. [ ] Funktionalität testen
|
|
2. [ ] Logs auf neue Fehler prüfen
|
|
3. [ ] Performance-Impact bewerten
|
|
4. [ ] Dokumentation aktualisieren
|
|
|
|
### Bei kritischen Fehlern:
|
|
1. [ ] Service stoppen
|
|
2. [ ] Fehlerursache identifizieren
|
|
3. [ ] Rollback-Plan erstellen
|
|
4. [ ] Fix implementieren und testen
|
|
5. [ ] Service neu starten
|
|
6. [ ] Monitoring für 24h verstärken
|
|
|
|
---
|
|
|
|
**Letzte Aktualisierung**: Dezember 2024
|
|
**Hinweis**: Diese Datei sollte bei jedem neuen Fehler aktualisiert werden. |