# ABSOLUTE DON'TS: - Verwendung von npm anstelle der Tailwind CDN - Implementierung von Content Security Policy (CSP) - UNTER KEINEN UMSTÄNDEN! - Implementierung von Cross-Site Request Forgery (CSRF) Schutz - Implementierung von Security Headers - Verwendung von TypeScript anstelle von JavaScript - Implementierung von OAuth oder anderen externen Authentifizierungsmethoden # HÄUFIGE FEHLER: - Verwendung der falschen Datenbank (die korrekte ist: database/systades.db) - Falsche Pfadangaben bei statischen Dateien - Vergessen der deutschen Spracheinstellungen in Templates - Nicht beachten der vorhandenen Projektstruktur - Falsche Einbindung der Neural Network Background Animation - Verwendung von englischen Variablennamen in deutschen Funktionen - Vergessen der Mindmap-Datenstruktur gemäß der Roadmap - NameError bei Verwendung von 'follows' anstatt 'user_follows' in API Endpunkten - 404 Fehler bei /auth/login weil Route als /login definiert ist # Häufige Fehler und Lösungen ## SQLAlchemy Beziehungsfehler ### Fehler: "AmbiguousForeignKeysError - Could not determine join condition" **Fehlerbeschreibung:** ``` sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship User.notifications - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table. ``` **Ursache:** SQLAlchemy kann nicht bestimmen, welcher Foreign Key für eine Beziehung verwendet werden soll, wenn mehrere Foreign Keys zwischen zwei Tabellen existieren. In diesem Fall hat die `Notification` Tabelle sowohl `user_id` (Empfänger) als auch `related_user_id` (Auslöser) als Foreign Keys zur `User` Tabelle. **Lösung:** 1. **Foreign Keys explizit angeben in der User-Klasse:** ```python # In models.py - User Klasse notifications = db.relationship('Notification', foreign_keys='Notification.user_id', backref='user', lazy=True, cascade="all, delete-orphan") ``` 2. **Foreign Keys in der Notification-Klasse spezifizieren:** ```python # In models.py - Notification Klasse related_user = db.relationship('User', foreign_keys=[related_user_id]) related_post = db.relationship('SocialPost', foreign_keys=[related_post_id]) related_comment = db.relationship('SocialComment', foreign_keys=[related_comment_id]) related_thought = db.relationship('Thought', foreign_keys=[related_thought_id]) ``` 3. **Datenbank nach Änderungen aktualisieren:** ```bash python3.11 -c "from app import app, db; from models import *; app.app_context().push(); db.create_all(); print('Datenbank erfolgreich aktualisiert')" ``` **Vorbeugende Maßnahmen:** - Immer `foreign_keys` Parameter verwenden, wenn mehrere Foreign Keys zwischen Tabellen existieren - Eindeutige Beziehungsnamen verwenden - Dokumentation der Beziehungen in den Modellen ### Fehler: "Eager loading cannot be applied - dynamic relationship" **Fehlerbeschreibung:** ``` 'MindMapNode.children' does not support object population - eager loading cannot be applied. ``` **Ursache:** SQLAlchemy kann kein Eager Loading (`joinedload`) auf `dynamic` Beziehungen anwenden. Dynamic Beziehungen sind Query-Objekte, die erst bei Zugriff ausgeführt werden. **Lösung:** 1. **Dynamic Beziehungen ohne Eager Loading verwenden:** ```python # Falsch - versucht joinedload auf dynamic relationship node = MindMapNode.query.options( joinedload(MindMapNode.children) # Fehler! ).get_or_404(node_id) # Richtig - dynamic relationship direkt verwenden node = MindMapNode.query.get_or_404(node_id) children = node.children.all() # Explizit alle Kinder laden has_children = node.children.count() > 0 # Anzahl prüfen ``` 2. **Beziehung von dynamic auf lazy ändern (falls Eager Loading benötigt):** ```python # In models.py - falls Eager Loading wirklich benötigt wird children = db.relationship( 'MindMapNode', secondary=node_relationship, primaryjoin=(node_relationship.c.parent_id == id), secondaryjoin=(node_relationship.c.child_id == id), backref=db.backref('parents', lazy='select'), # Nicht dynamic lazy='select' # Ermöglicht joinedload ) ``` 3. **Separate Queries für bessere Performance:** ```python # Hauptknoten laden node = MindMapNode.query.get_or_404(node_id) # Kinder in separater Query laden children = MindMapNode.query.join(node_relationship).filter( node_relationship.c.parent_id == node.id ).all() ``` **Vorbeugende Maßnahmen:** - Dokumentiere, welche Beziehungen `dynamic` sind - Verwende `lazy='select'` oder `lazy='joined'` wenn Eager Loading benötigt wird - Teste API-Endpunkte nach Modelländerungen ### Fehler: "404 Not Found - Admin API Endpoint" **Fehlerbeschreibung:** ``` 404 Not Found: The requested URL was not found on the server. Endpoint: /admin/api/dashboard-data, Method: GET ``` **Ursache:** Der Admin-API-Endpunkt `/admin/api/dashboard-data` existiert nicht in der Anwendung. **Lösung:** 1. **Admin-Dashboard-API-Route hinzufügen:** ```python @app.route('/admin/api/dashboard-data', methods=['GET']) @admin_required def admin_dashboard_data(): """Liefert Dashboard-Daten für den Admin-Bereich""" try: # Benutzerstatistiken total_users = User.query.count() active_users = User.query.filter_by(is_active=True).count() admin_users = User.query.filter_by(role='admin').count() # Weitere Statistiken... return jsonify({ 'success': True, 'data': { 'users': { 'total': total_users, 'active': active_users, 'admins': admin_users } # Weitere Daten... } }) except Exception as e: ErrorHandler.log_exception(e, "admin/api/dashboard-data") return jsonify({ 'success': False, 'error': 'Fehler beim Laden der Dashboard-Daten', 'details': str(e) }), 500 ``` 2. **Benötigte Imports hinzufügen:** ```python from models import ( # ... bestehende Imports ... SocialPost, SocialComment, Notification ) ``` **Vorbeugende Maßnahmen:** - Alle API-Endpunkte dokumentieren - Regelmäßige Tests der Admin-Funktionalität - Fehlerbehandlung für alle API-Routen implementieren ### Fehler: "NameError: name 'follows' is not defined" **Fehlerbeschreibung:** ```python NameError: name 'follows' is not defined Endpoint: /api/discover/users, Method: GET ``` **Ursache:** Der Code versucht auf eine Variable namens `follows` zuzugreifen, aber die korrekte Tabelle heißt `user_follows` (definiert in models.py). **Lösung:** 1. **Korrekten Tabellennamen verwenden:** ```python # Falsch not_following_subquery = db.session.query(follows.c.followed_id).filter( follows.c.follower_id == current_user.id ).subquery() # Richtig not_following_subquery = db.session.query(user_follows.c.followed_id).filter( user_follows.c.follower_id == current_user.id ).subquery() ``` 2. **Import prüfen:** ```python # In app.py - sicherstellen dass user_follows importiert ist from models import ( db, User, Thought, Comment, MindMapNode, ThoughtRelation, ThoughtRating, RelationType, Category, UserMindmap, UserMindmapNode, MindmapNote, node_thought_association, user_thought_bookmark, node_relationship, MindmapShare, PermissionType, SocialPost, SocialComment, Notification, user_follows # Wichtig: user_follows importieren ) ``` **Vorbeugende Maßnahmen:** - Tabellennamen in models.py dokumentieren - Konsistente Benennung verwenden - Import-Listen regelmäßig prüfen ### Fehler: "404 Not Found: /auth/login" **Fehlerbeschreibung:** ``` 404 Not Found: The requested URL was not found on the server. Endpoint: /auth/login, Method: GET ``` **Ursache:** Die Login-Route ist als `/login` definiert, aber das Frontend oder Links versuchen auf `/auth/login` zuzugreifen. **Lösung:** 1. **Kompatibilitäts-Route hinzufügen:** ```python # Haupt-Login-Route @app.route('/login', methods=['GET', 'POST']) @log_execution_time(component='AUTH') def login(): # ... Login-Logik ... return render_template('login.html') # Kompatibilitäts-Route für /auth/login @app.route('/auth/login', methods=['GET', 'POST']) @log_execution_time(component='AUTH') def auth_login(): """Redirect /auth/login to /login for compatibility""" return redirect(url_for('login')) ``` 2. **Weitere Auth-Routen für Konsistenz:** ```python @app.route('/auth/register', methods=['GET', 'POST']) def auth_register(): return redirect(url_for('register')) @app.route('/auth/logout') def auth_logout(): return redirect(url_for('logout')) ``` **Vorbeugende Maßnahmen:** - URL-Struktur konsistent halten - Alle verwendeten Routes dokumentieren - Redirects für Legacy-URLs implementieren ## Flask Application Context Fehler ### Fehler: "Working outside of application context" **Fehlerbeschreibung:** ``` RuntimeError: Working outside of application context. This typically means that you attempted to use functionality that needed the current application. To solve this, set up an application context with app.app_context(). See the documentation for more information. ``` **Ursache:** Der Logger versucht auf Flask's `g` (global context) oder `request` zuzugreifen, bevor ein Flask Application Context existiert. Das passiert oft während des Imports oder bei der Initialisierung. **Lösung:** 1. **Logger Context-Safe machen:** ```python # In utils/logger.py JSONFormatter try: from flask import has_app_context, has_request_context if has_app_context(): if hasattr(g, 'user_id'): log_entry['user_id'] = g.user_id except (ImportError, RuntimeError): # Flask ist nicht verfügbar oder kein App-Context pass ``` 2. **Zirkuläre Imports vermeiden:** ```python # Anstatt direkter Import von app: # from app import app # Verwende lazy loading: def get_app(): try: from flask import current_app return current_app except RuntimeError: from app import app return app ``` 3. **Fehlende Imports hinzufügen:** ```python # Sicherstellen, dass alle benötigten Module importiert sind import time # Für g.start_time from utils.logger import performance_monitor, log_user_activity ``` **Vorbeugende Maßnahmen:** - Immer `has_app_context()` und `has_request_context()` prüfen - Lazy Loading für Flask-App-Imports verwenden - Try-Catch für Flask Context-abhängige Operationen ## Datenbankfehler ### Fehler: "no such column: user.password" **Fehlerbeschreibung:** ``` sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: user.password [SQL: SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.password AS user_password, user.created_at AS user_created_at, user.is_active AS user_is_active, user.role AS user_role FROM user WHERE user.id = ?] ``` **Ursache:** Die Spalte `password` fehlt in der Tabelle `user` der SQLite-Datenbank. Dies kann durch eine unvollständige Datenbankinitialisierung oder ein fehlerhaftes Schema-Update verursacht worden sein. **Lösung:** 1. **Datenbank reparieren mit dem Fix-Skript** ```bash python fix_user_table.py ``` Dieses Skript: - Prüft, ob die Tabelle `user` existiert und erstellt sie, falls nicht - Prüft, ob die Spalte `password` existiert und fügt sie hinzu, falls nicht 2. **Standardbenutzer erstellen** ```bash python create_default_users.py ``` Dieses Skript: - Erstellt Standardbenutzer (admin, user), falls keine vorhanden sind - Setzt Passwörter mit korrektem Hashing 3. **Datenbank testen** ```bash python test_app.py ``` Dieses Skript überprüft: - Ob die Datenbank existiert - Ob die Tabelle `user` korrekt konfiguriert ist - Ob Benutzer vorhanden sind ## Häufige Ursachen für Datenbankfehler 1. **Inkonsistente Datenbankschemas** - Unterschiede zwischen dem SQLAlchemy-Modell und der tatsächlichen Datenbankstruktur - Fehlende Spalten, die in den Modellen definiert sind 2. **Falsche Datenbankinitialisierung** - Die Datenbank wurde nicht korrekt initialisiert - Fehler bei der Migration oder dem Schema-Update 3. **Datenbankdatei-Korrumpierung** - Die SQLite-Datenbankdatei wurde beschädigt - Lösung: Sicherung wiederherstellen oder Datenbank neu erstellen ## Vorbeugende Maßnahmen 1. **Regelmäßige Backups** - Tägliche Sicherung der Datenbankdatei 2. **Schema-Validierung** - Regelmäßige Überprüfung der Datenbankstruktur - Automatisierte Tests für Datenbankschema 3. **Datenbankmigration** - Verwenden Sie Flask-Migrate für strukturierte Datenbank-Updates - Dokumentieren Sie alle Schemaänderungen ## Content Security Policy (CSP) ### Problem: Externe Ressourcen werden nicht geladen **Fehler:** Externe Ressourcen wie CDNs werden nicht korrekt geladen. **Lösung:** 1. Stellen Sie sicher, dass die URLs in den Templates korrekt sind: ```html ``` 2. Überprüfen Sie die Netzwerkverbindung und ob die CDN-Domains erreichbar sind. 3. Verwenden Sie lokale Ressourcen als Alternative: ```html ``` ### Problem: CSP-Fehler (script-src-elem 'none', font-src 'none', etc.) **Fehler:** Skripte werden aufgrund von CSP-Einschränkungen blockiert. **Lösung:** 1. WICHTIG: CSP-Einschränkungen NICHT implementieren! Diese sind im Projekt unerwünscht. 2. Falls CSP-Header bereits vorhanden sind, entfernen Sie diese aus der Anwendung: ```python # Entfernen Sie diesen Code, falls vorhanden: # @app.after_request # def add_security_headers(response): # response.headers['Content-Security-Policy'] = '...' # return response ``` 3. Stellen Sie sicher, dass externe Ressourcen direkt geladen werden: ```html ``` 4. Für Inline-Skripte keine Nonce verwenden: ```html ``` ### Problem: Tailwind CSS CDN wird blockiert **Fehler:** Tailwind CSS kann nicht von CDN geladen werden. **Lösung:** 1. Verwenden Sie die lokale Version von Tailwind CSS: ```html ``` 2. Alternativ können Sie die CDN-Version direkt im Template einbinden: ```html ``` 3. Stellen Sie sicher, dass die Datei `static/css/tailwind.min.css` existiert und aktuell ist. ## Authentifizierung ### Problem: Login funktioniert nicht **Fehler:** Benutzer kann sich nicht einloggen. **Lösung:** 1. Standard-Admin-Benutzer erstellen: `python TOOLS.py user:admin` 2. Passwort zurücksetzen: `python TOOLS.py user:reset-pw -u USERNAME -p NEWPASSWORD` ## Neural Network Background ### Problem: Hintergrund-Animation wird nicht angezeigt **Fehler:** Die Neural Network Animation im Hintergrund erscheint nicht. **Lösung:** 1. Überprüfen Sie, ob die Datei `static/neural-network-background.js` korrekt eingebunden ist: ```html ``` 2. Initialisieren Sie die Animation im Template: ```html ``` 3. Stellen Sie sicher, dass keine CSS-Regeln die Animation überdecken: ```css #neural-network-background { z-index: -10; opacity: 1; } ``` ## Mindmap-Funktionalität ### Problem: Mindmap-Daten werden nicht geladen **Fehler:** Die dynamische Mindmap zeigt keine Daten an. **Lösung:** 1. Überprüfen Sie die API-Endpunkte für die Mindmap-Daten: ```python @app.route('/api/mindmap/nodes', methods=['GET']) def get_mindmap_nodes(): # Implementierung... ``` 2. Stellen Sie sicher, dass die AJAX-Anfragen korrekt implementiert sind: ```javascript fetch('/api/mindmap/nodes') .then(response => response.json()) .then(data => { // Verarbeitung der Mindmap-Daten }); ``` 3. Überprüfen Sie die Datenbankeinträge für Mindmap-Knoten und -Verbindungen. ## ChatGPT-Assistent ### Problem: Assistent reagiert nicht auf Eingaben **Fehler:** Der ChatGPT-Assistent verarbeitet keine Benutzereingaben. **Lösung:** 1. Überprüfen Sie die Einbindung der JavaScript-Datei: ```html ``` 2. Stellen Sie sicher, dass der Assistent korrekt initialisiert wird: ```javascript document.addEventListener('DOMContentLoaded', () => { const assistant = new ChatGPTAssistant(); assistant.initialize(); }); ``` 3. Überprüfen Sie die API-Endpunkte für die Kommunikation mit dem Assistenten. # 🔧 SysTades Social Network - Häufige Fehler und Lösungen ## 📋 Überblick Diese Datei enthält eine Sammlung häufig auftretender Fehler und deren bewährte Lösungen für die SysTades Social Network Anwendung. --- ## 🗄️ Datenbankfehler ### 1. Tabellen existieren nicht **Fehler**: `sqlite3.OperationalError: no such table: users` **Ursache**: Datenbank wurde nicht initialisiert **Lösung**: ```bash python3.11 init_db.py ``` ### 2. Foreign Key Constraints **Fehler**: `FOREIGN KEY constraint failed` **Ursache**: Versuch, einen Datensatz zu löschen, der von anderen referenziert wird **Lösung**: ```python # Erst abhängige Datensätze löschen user_follows.query.filter(user_follows.c.follower_id == user_id).delete() user_follows.query.filter(user_follows.c.followed_id == user_id).delete() # Dann Hauptdatensatz user = User.query.get(user_id) db.session.delete(user) db.session.commit() ``` ### 3. Migration Fehler **Fehler**: `alembic.util.exc.CommandError: Can't locate revision identified by` **Ursache**: Inkonsistente Migration History **Lösung**: ```bash rm -rf migrations/ flask db init flask db migrate -m "Initial migration" flask db upgrade ``` --- ## 🔐 Authentifizierung & Session Fehler ### 4. Login erforderlich Fehler **Fehler**: `401 Unauthorized` **Ursache**: Benutzer nicht angemeldet für geschützte Route **Lösung**: ```python @login_required def protected_route(): # Prüfe explizit auf current_user if not current_user.is_authenticated: return jsonify({'error': 'Login erforderlich'}), 401 ``` ### 5. Session Timeout **Fehler**: Session läuft ab, Benutzer wird ausgeloggt **Ursache**: Kurze Session-Lebensdauer **Lösung**: ```python # In app.py app.permanent_session_lifetime = timedelta(days=7) ``` ### 6. CSRF Token Fehler **Fehler**: `400 Bad Request: The CSRF token is missing` **Ursache**: Fehlender oder ungültiger CSRF Token **Lösung**: ```html ``` --- ## 🌐 API & AJAX Fehler ### 7. JSON Parsing Fehler **Fehler**: `JSONDecodeError: Expecting value` **Ursache**: Leerer oder ungültiger JSON Body **Lösung**: ```python try: data = request.get_json() if not data: return jsonify({'error': 'Leerer JSON Body'}), 400 except Exception as e: return jsonify({'error': 'Ungültiges JSON Format'}), 400 ``` ### 8. CORS Fehler **Fehler**: `Access-Control-Allow-Origin` header fehlt **Ursache**: Frontend und Backend auf verschiedenen Ports **Lösung**: ```python # CORS headers explizit setzen @app.after_request def after_request(response): response.headers.add('Access-Control-Allow-Origin', '*') response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization') response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') return response ``` ### 9. 413 Request Entity Too Large **Fehler**: File upload zu groß **Ursache**: Datei überschreitet MAX_CONTENT_LENGTH **Lösung**: ```python app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB ``` --- ## 🎨 Frontend & UI Fehler ### 10. JavaScript Fehler **Fehler**: `TypeError: Cannot read property of undefined` **Ursache**: DOM Element nicht gefunden **Lösung**: ```javascript const element = document.getElementById('myElement'); if (element) { // Nur ausführen wenn Element existiert element.addEventListener('click', handleClick); } ``` ### 11. CSS nicht geladen **Fehler**: Styling fehlt komplett **Ursache**: Falsche CSS-Pfade oder Cache-Problem **Lösung**: ```html ``` ### 12. Mobile Responsiveness **Fehler**: UI bricht auf mobilen Geräten **Ursache**: Fehlende Viewport Meta-Tag oder falsche CSS **Lösung**: ```html ``` --- ## 📁 Datei & Upload Fehler ### 13. Datei Upload Fehler **Fehler**: `OSError: [Errno 2] No such file or directory` **Ursache**: Upload-Verzeichnis existiert nicht **Lösung**: ```python import os upload_folder = 'static/uploads' os.makedirs(upload_folder, exist_ok=True) ``` ### 14. Dateiberechtigungen **Fehler**: `PermissionError: [Errno 13] Permission denied` **Ursache**: Falsche Dateiberechtigungen **Lösung**: ```bash chmod 755 static/ chmod -R 644 static/uploads/ ``` --- ## 🚀 Performance Probleme ### 15. Langsame Datenbankabfragen **Problem**: Seitenladezeiten > 3 Sekunden **Ursache**: Fehlende Indizes, N+1 Queries **Lösung**: ```python # Indizes hinzufügen class User(db.Model): username = db.Column(db.String(80), unique=True, nullable=False, index=True) # Eager Loading verwenden posts = SocialPost.query.options(joinedload(SocialPost.author)).all() ``` ### 16. Memory Leaks **Problem**: Speicherverbrauch steigt kontinuierlich **Ursache**: Sessions nicht geschlossen, große Objekte im Memory **Lösung**: ```python try: # Database operations db.session.commit() except Exception as e: db.session.rollback() raise finally: db.session.close() ``` ### 17. JavaScript Performance **Problem**: UI friert ein bei großen Datenmengen **Ursache**: Blocking Operations im Main Thread **Lösung**: ```javascript // Pagination verwenden const POSTS_PER_PAGE = 10; // Virtual Scrolling für große Listen function renderVisiblePosts(startIndex, endIndex) { // Nur sichtbare Posts rendern } ``` --- ## 🔄 Real-time & WebSocket Fehler ### 18. WebSocket Connection Failed **Fehler**: `WebSocket connection to 'ws://localhost:5000/' failed` **Ursache**: WebSocket Server nicht konfiguriert **Lösung**: ```python # Für Real-time Features from flask_socketio import SocketIO socketio = SocketIO(app, cors_allowed_origins="*") ``` ### 19. Notification Polling Performance **Problem**: Zu viele API Calls für Notifications **Ursache**: Zu kurze Polling-Intervalle **Lösung**: ```javascript // Längere Intervalle verwenden setInterval(pollNotifications, 30000); // 30 Sekunden statt 5 ``` --- ## 🧪 Testing & Debugging ### 20. Unit Test Fehler **Fehler**: Tests schlagen fehl wegen Datenbankzustand **Ursache**: Tests teilen sich Datenbankzustand **Lösung**: ```python @pytest.fixture def client(): app.config['TESTING'] = True app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' with app.test_client() as client: with app.app_context(): db.create_all() yield client db.drop_all() ``` ### 21. Debug Mode Probleme **Problem**: Änderungen werden nicht übernommen **Ursache**: Debug Mode nicht aktiviert **Lösung**: ```python if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000) ``` --- ## 🔧 Deployment Fehler ### 22. Gunicorn Worker Timeout **Fehler**: `[CRITICAL] WORKER TIMEOUT` **Ursache**: Lange laufende Requests **Lösung**: ```bash gunicorn --timeout 120 --workers 4 app:app ``` ### 23. Static Files nicht gefunden **Fehler**: 404 für CSS/JS Files in Production **Ursache**: Nginx nicht konfiguriert für static files **Lösung**: ```nginx location /static { alias /path/to/website/static; expires 1y; add_header Cache-Control "public, immutable"; } ``` ### 24. Environment Variables **Fehler**: `KeyError: 'SECRET_KEY'` **Ursache**: .env Datei nicht geladen in Production **Lösung**: ```bash # In start.sh export FLASK_ENV=production export SECRET_KEY="your-secret-key" python3.11 app.py ``` --- ## 🐛 Logging & Monitoring ### 25. Logs nicht geschrieben **Problem**: Log-Dateien bleiben leer **Ursache**: Falsche Berechtigungen oder Pfad **Lösung**: ```python import os log_dir = 'logs' os.makedirs(log_dir, exist_ok=True) ``` ### 26. Log Rotation **Problem**: Log-Dateien werden zu groß **Ursache**: Keine Log-Rotation konfiguriert **Lösung**: ```python from logging.handlers import RotatingFileHandler handler = RotatingFileHandler( 'logs/app.log', maxBytes=10*1024*1024, # 10MB backupCount=5 ) ``` --- ## 📊 Social Network Spezifische Fehler ### 27. Like/Unlike Race Conditions **Problem**: Doppelte Likes bei schnellen Klicks **Ursache**: Race Condition zwischen Requests **Lösung**: ```python from sqlalchemy import func # Atomic operation existing_like = PostLike.query.filter_by( user_id=user_id, post_id=post_id ).first() if existing_like: db.session.delete(existing_like) post.like_count = func.greatest(post.like_count - 1, 0) else: new_like = PostLike(user_id=user_id, post_id=post_id) db.session.add(new_like) post.like_count += 1 db.session.commit() ``` ### 28. Infinite Scroll Duplikate **Problem**: Gleiche Posts werden mehrfach geladen **Ursache**: Pagination offset/page confusion **Lösung**: ```python # Cursor-based pagination verwenden last_id = request.args.get('last_id', type=int) query = SocialPost.query.order_by(SocialPost.id.desc()) if last_id: query = query.filter(SocialPost.id < last_id) posts = query.limit(10).all() ``` ### 29. Notification Spam **Problem**: Zu viele Benachrichtigungen für gleiche Aktion **Ursache**: Keine Deduplizierung **Lösung**: ```python # Prüfe auf existierende Notification existing = Notification.query.filter_by( user_id=target_user_id, type='like', related_post_id=post_id, created_at=func.date(func.now()) ).first() if not existing: # Nur neue Notification erstellen notification = Notification(...) db.session.add(notification) ``` --- ## 🔍 Quick Debugging Commands ```bash # Datenbankzustand prüfen sqlite3 instance/site.db ".tables" sqlite3 instance/site.db "SELECT * FROM users LIMIT 5;" # Logs live verfolgen tail -f logs/app.log tail -f logs/errors.log # Port prüfen netstat -tulpn | grep :5000 # Python Dependencies prüfen pip3.11 list | grep -i flask # Datenbankmigrationen flask db current flask db history # Performance monitoring python3.11 -m cProfile -o profile.stats app.py ``` --- ## 📋 Präventive Maßnahmen ### 1. Code Quality - Immer Validierung für User Input - Try-Catch Blöcke für externe API Calls - Logging für alle kritischen Operationen ### 2. Testing - Unit Tests für alle API Endpoints - Integration Tests für User Flows - Load Testing für Performance ### 3. Monitoring - Error Rate Tracking - Response Time Monitoring - Database Query Performance ### 4. Security - Input Sanitization - SQL Injection Prevention - XSS Protection --- ## 🔄 Update Checklist Vor jedem Update prüfen: - [ ] Backup der Datenbank erstellen - [ ] Tests ausführen - [ ] Dependencies aktualisieren - [ ] Logs auf Fehler prüfen - [ ] Performance Metrics vergleichen --- **Letzte Aktualisierung**: Aktuelle Version **Version**: 2.0.0 - Social Network Release **Wartung**: Kontinuierlich aktualisiert > **💡 Tipp**: Bei neuen Fehlern immer diese Datei aktualisieren und die Lösung dokumentieren! ## Logging-System ### Verbessertes Logging mit Emojis und Farben Das System verwendet jetzt ein erweiterte Logging-System mit visuellen Verbesserungen: #### Features: - 🎨 **Farbige Konsolen-Ausgabe** mit ANSI-Codes - 📝 **Emoji-basierte Kategorisierung** für bessere Übersicht - 🔍 **Komponenten-spezifisches Logging** (AUTH, API, DB, SOCIAL, ERROR, etc.) - ⏱️ **Performance-Monitoring** mit Zeitdauer-Tracking - 📊 **Strukturierte JSON-Logs** für externe Analyse - 🚀 **Decorator-basierte Instrumentierung** für automatisches Logging #### Verwendung: ```python from utils.logger import get_logger, log_execution_time, log_api_call, performance_monitor # Logger-Instanz abrufen logger = get_logger('SysTades') # Einfache Logs mit Komponenten-Kategorisierung logger.info("Benutzer angemeldet", component='AUTH', user='username') logger.error("API-Fehler aufgetreten", component='API') logger.warning("Datenbank-Verbindung langsam", component='DB') # Spezielle Logging-Methoden logger.auth_success('username', ip='192.168.1.1') logger.user_action('username', 'mindmap_created', 'Neue Mindmap erstellt') logger.performance_metric('response_time', 250.5, 'ms') # Decorator für automatisches API-Logging @log_api_call def my_api_endpoint(): return jsonify({'success': True}) # Decorator für Performance-Monitoring @performance_monitor('database_operation') def complex_database_query(): # Komplexe Datenbankabfrage pass # Decorator für Ausführungszeit-Tracking @log_execution_time(component='AUTH') def login_process(): # Anmeldeprozess pass ``` #### Log-Kategorien und Emojis: | Komponente | Emoji | Beschreibung | |------------|-------|--------------| | AUTH | 🔐 | Authentifizierung und Autorisierung | | API | 🌐 | API-Endpunkte und REST-Calls | | DB | 🗄️ | Datenbankoperationen | | SOCIAL | 👥 | Social-Media-Funktionen | | SYSTEM | ⚙️ | System-Events | | ERROR | 💥 | Fehlerbehandlung | | SECURITY | 🛡️ | Sicherheitsereignisse | | PERFORMANCE | ⚡ | Performance-Metriken | #### Log-Level mit Emojis: | Level | Emoji | Verwendung | |-------|-------|------------| | DEBUG | 🔍 | Entwicklung und Debugging | | INFO | ✅ | Normale Informationen | | WARNING | ⚠️ | Warnungen | | ERROR | ❌ | Fehler | | CRITICAL | 🚨 | Kritische Systemfehler | #### Konfiguration: Die Logger-Konfiguration erfolgt über die `setup_logging()` Funktion: ```python # Automatische Konfiguration bei App-Start setup_logging(app, log_level='INFO') # Manuelle Konfiguration from utils.logger import LoggerConfig LoggerConfig.LOG_DIR = 'custom_logs' LoggerConfig.MAX_LOG_SIZE = 20 * 1024 * 1024 # 20MB ``` #### Ausgabe-Beispiel: ``` ⏰ 14:32:15.123 │ ✅ INFO │ 🔐 [AUTH ] │ 🚪 Benutzer admin angemeldet 👤 admin 🌍 192.168.1.1 ⏰ 14:32:16.456 │ ❌ ERROR │ 💥 [ERROR ] │ 💥 API-Fehler: Verbindung zur Datenbank fehlgeschlagen ⚡ 1250.00ms ⏰ 14:32:17.789 │ ⚠️ WARNING │ 🗄️ [DB ] │ ⏱️ Langsame Datenbankabfrage detected 👤 admin ⚡ 2500.00ms ``` ### Integration in die App Die Hauptanwendung wurde vollständig auf das neue Logging-System umgestellt: - Alle `print()` Statements wurden durch strukturierte Logs ersetzt - Authentication-Events werden automatisch protokolliert - API-Calls werden mit Performance-Metriken geloggt - Datenbankoperationen haben detaillierte Logging-Ausgaben - Fehlerbehandlung nutzt das zentrale Logging-System ### Troubleshooting **Problem**: Logs erscheinen nicht in der Konsole **Lösung**: Überprüfen Sie das LOG_LEVEL in der .env-Datei: ```bash LOG_LEVEL=DEBUG # Für detaillierte Logs LOG_LEVEL=INFO # Für normale Logs ``` **Problem**: Farben werden nicht angezeigt **Lösung**: Stellen Sie sicher, dass Ihr Terminal ANSI-Codes unterstützt **Problem**: Log-Dateien werden zu groß **Lösung**: Konfigurieren Sie die Log-Rotation: ```python LoggerConfig.MAX_LOG_SIZE = 5 * 1024 * 1024 # 5MB LoggerConfig.BACKUP_COUNT = 10 # 10 Backup-Dateien ``` --- ## 🚨 HÄUFIGE FEHLER UND LÖSUNGEN ## SQLAlchemy Relationship Fehler ### ❌ AttributeError: followed_id beim Social Feed **Problem:** `AttributeError: followed_id` - Der Fehler tritt auf, wenn versucht wird, auf eine Spalte in einer Subquery zuzugreifen, die nicht existiert. **Fehlerhafter Code:** ```python def get_feed_posts(self, limit=20): followed_users = self.following.subquery() return SocialPost.query.join( followed_users, SocialPost.user_id == followed_users.c.followed_id ).order_by(SocialPost.created_at.desc()).limit(limit) ``` **Lösung:** ```python def get_feed_posts(self, limit=20): # Hole alle User-IDs von Benutzern, denen ich folge followed_user_ids = [user.id for user in self.following] # Hole Posts von diesen Benutzern und meinen eigenen Posts return SocialPost.query.filter( SocialPost.user_id.in_(followed_user_ids + [self.id]) ).order_by(SocialPost.created_at.desc()).limit(limit) ``` **Ursache:** Die `self.following` Beziehung gibt User-Objekte zurück, nicht die Zwischentabelle `user_follows`. Bei der Subquery-Erstellung wird versucht, auf `followed_id` zuzugreifen, aber die Subquery enthält User-Felder, nicht die Spalten der Zwischentabelle. --- ## SQL UNION Syntax Fehler ### Fehler: "sqlite3.OperationalError: near 'UNION': syntax error" **Fehlerbeschreibung:** ``` sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) near "UNION": syntax error [SQL: SELECT anon_1.social_post_id AS anon_1_social_post_id ... FROM ((SELECT social_post.id AS social_post_id ... LIMIT ? OFFSET ?) UNION SELECT social_post.id AS social_post_id ... WHERE social_post.user_id = ?) AS anon_1 ORDER BY anon_1.social_post_created_at DESC LIMIT ? OFFSET ?] ``` **Ursache:** SQLite hat spezielle Regeln für UNION-Abfragen. Das Problem tritt auf, wenn man versucht, eine Query mit bereits angewendetem LIMIT/OFFSET (Paginierung) in einer UNION zu verwenden. SQLAlchemy's `paginate()` fügt automatisch LIMIT und OFFSET hinzu, was zu ungültigem SQL führt. **Problematischer Code:** ```python # FEHLERHAFT - Union von paginierten Queries followed_posts = current_user.get_feed_posts(limit=100) # Hat bereits LIMIT own_posts = SocialPost.query.filter_by(user_id=current_user.id) all_posts = followed_posts.union(own_posts).order_by(SocialPost.created_at.desc()) posts = all_posts.paginate(page=page, per_page=posts_per_page) # Zusätzliches LIMIT/OFFSET ``` **Lösung:** 1. **Eine einzige Query mit IN-Operator verwenden:** ```python # RICHTIG - Eine einzelne Query ohne Union @app.route('/feed') @login_required def social_feed(): page = request.args.get('page', 1, type=int) posts_per_page = 10 # Alle User-IDs sammeln (gefolgte + eigene) followed_user_ids = [user.id for user in current_user.following] all_user_ids = followed_user_ids + [current_user.id] # Eine einzige Query für alle Posts all_posts = SocialPost.query.filter( SocialPost.user_id.in_(all_user_ids) ).order_by(SocialPost.created_at.desc()) posts = all_posts.paginate( page=page, per_page=posts_per_page, error_out=False ) return render_template('social/feed.html', posts=posts) ``` 2. **Model-Methode anpassen:** ```python # In models.py - User Klasse def get_feed_posts(self, limit=20): """Holt Posts für den Feed (von gefolgten Benutzern)""" # Alle User-IDs sammeln followed_user_ids = [user.id for user in self.following] all_user_ids = followed_user_ids + [self.id] # Eine einzige Query return SocialPost.query.filter( SocialPost.user_id.in_(all_user_ids) ).order_by(SocialPost.created_at.desc()).limit(limit) ``` 3. **API-Endpunkt entsprechend anpassen:** ```python @app.route('/api/feed') @login_required def get_feed_posts(): page = request.args.get('page', 1, type=int) per_page = request.args.get('per_page', 10, type=int) # Gleiche Logik wie im Web-Endpunkt followed_user_ids = [user.id for user in current_user.following] all_user_ids = followed_user_ids + [current_user.id] all_posts = SocialPost.query.filter( SocialPost.user_id.in_(all_user_ids) ).order_by(SocialPost.created_at.desc()) posts = all_posts.paginate( page=page, per_page=per_page, error_out=False ) return jsonify({ 'success': True, 'posts': [post.to_dict() for post in posts.items], 'has_next': posts.has_next, 'has_prev': posts.has_prev, 'page': posts.page, 'pages': posts.pages, 'total': posts.total }) ``` **Vorbeugende Maßnahmen:** - Vermeide UNION mit bereits paginierten Queries - Verwende `IN`-Operator für einfache Filter-Kombinationen - Teste SQL-Queries vor Produktionsfreigabe - Dokumentiere komplexe Query-Logik ausführlich **Weitere UNION-Regeln für SQLite:** - UNION-Queries müssen die gleiche Anzahl von Spalten haben - Spaltentypen müssen kompatibel sein - ORDER BY nur am Ende der kompletten UNION-Query - LIMIT/OFFSET nur am Ende, nicht in Subqueries ## SQLAlchemy Beziehungsfehler