37 KiB
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:
-
Foreign Keys explizit angeben in der User-Klasse:
# In models.py - User Klasse notifications = db.relationship('Notification', foreign_keys='Notification.user_id', backref='user', lazy=True, cascade="all, delete-orphan") -
Foreign Keys in der Notification-Klasse spezifizieren:
# 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]) -
Datenbank nach Änderungen aktualisieren:
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_keysParameter 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:
-
Dynamic Beziehungen ohne Eager Loading verwenden:
# 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 -
Beziehung von dynamic auf lazy ändern (falls Eager Loading benötigt):
# 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 ) -
Separate Queries für bessere Performance:
# 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
dynamicsind - Verwende
lazy='select'oderlazy='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:
-
Admin-Dashboard-API-Route hinzufügen:
@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 -
Benötigte Imports hinzufügen:
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:
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:
-
Korrekten Tabellennamen verwenden:
# 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() -
Import prüfen:
# 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:
-
Kompatibilitäts-Route hinzufügen:
# 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')) -
Weitere Auth-Routen für Konsistenz:
@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:
-
Logger Context-Safe machen:
# 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 -
Zirkuläre Imports vermeiden:
# 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 -
Fehlende Imports hinzufügen:
# 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()undhas_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:
-
Datenbank reparieren mit dem Fix-Skript
python fix_user_table.pyDieses Skript:
- Prüft, ob die Tabelle
userexistiert und erstellt sie, falls nicht - Prüft, ob die Spalte
passwordexistiert und fügt sie hinzu, falls nicht
- Prüft, ob die Tabelle
-
Standardbenutzer erstellen
python create_default_users.pyDieses Skript:
- Erstellt Standardbenutzer (admin, user), falls keine vorhanden sind
- Setzt Passwörter mit korrektem Hashing
-
Datenbank testen
python test_app.pyDieses Skript überprüft:
- Ob die Datenbank existiert
- Ob die Tabelle
userkorrekt konfiguriert ist - Ob Benutzer vorhanden sind
Häufige Ursachen für Datenbankfehler
-
Inkonsistente Datenbankschemas
- Unterschiede zwischen dem SQLAlchemy-Modell und der tatsächlichen Datenbankstruktur
- Fehlende Spalten, die in den Modellen definiert sind
-
Falsche Datenbankinitialisierung
- Die Datenbank wurde nicht korrekt initialisiert
- Fehler bei der Migration oder dem Schema-Update
-
Datenbankdatei-Korrumpierung
- Die SQLite-Datenbankdatei wurde beschädigt
- Lösung: Sicherung wiederherstellen oder Datenbank neu erstellen
Vorbeugende Maßnahmen
-
Regelmäßige Backups
- Tägliche Sicherung der Datenbankdatei
-
Schema-Validierung
- Regelmäßige Überprüfung der Datenbankstruktur
- Automatisierte Tests für Datenbankschema
-
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:
-
Stellen Sie sicher, dass die URLs in den Templates korrekt sind:
<link href="https://cdn.tailwindcss.com" rel="stylesheet"> -
Überprüfen Sie die Netzwerkverbindung und ob die CDN-Domains erreichbar sind.
-
Verwenden Sie lokale Ressourcen als Alternative:
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
Problem: CSP-Fehler (script-src-elem 'none', font-src 'none', etc.)
Fehler: Skripte werden aufgrund von CSP-Einschränkungen blockiert.
Lösung:
-
WICHTIG: CSP-Einschränkungen NICHT implementieren! Diese sind im Projekt unerwünscht.
-
Falls CSP-Header bereits vorhanden sind, entfernen Sie diese aus der Anwendung:
# Entfernen Sie diesen Code, falls vorhanden: # @app.after_request # def add_security_headers(response): # response.headers['Content-Security-Policy'] = '...' # return response -
Stellen Sie sicher, dass externe Ressourcen direkt geladen werden:
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <script src="{{ url_for('static', filename='js/alpine.min.js') }}" defer></script> -
Für Inline-Skripte keine Nonce verwenden:
<script> // Inline-JavaScript-Code ohne Einschränkungen </script>
Problem: Tailwind CSS CDN wird blockiert
Fehler: Tailwind CSS kann nicht von CDN geladen werden.
Lösung:
-
Verwenden Sie die lokale Version von Tailwind CSS:
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet"> -
Alternativ können Sie die CDN-Version direkt im Template einbinden:
<script src="https://cdn.tailwindcss.com"></script> -
Stellen Sie sicher, dass die Datei
static/css/tailwind.min.cssexistiert und aktuell ist.
Authentifizierung
Problem: Login funktioniert nicht
Fehler: Benutzer kann sich nicht einloggen.
Lösung:
- Standard-Admin-Benutzer erstellen:
python TOOLS.py user:admin - 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:
-
Überprüfen Sie, ob die Datei
static/neural-network-background.jskorrekt eingebunden ist:<script src="{{ url_for('static', filename='neural-network-background.js') }}"></script> -
Initialisieren Sie die Animation im Template:
<script> document.addEventListener('DOMContentLoaded', () => { const background = new NeuralNetworkBackground(); background.initialize(); background.animate(); }); </script> -
Stellen Sie sicher, dass keine CSS-Regeln die Animation überdecken:
#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:
-
Überprüfen Sie die API-Endpunkte für die Mindmap-Daten:
@app.route('/api/mindmap/nodes', methods=['GET']) def get_mindmap_nodes(): # Implementierung... -
Stellen Sie sicher, dass die AJAX-Anfragen korrekt implementiert sind:
fetch('/api/mindmap/nodes') .then(response => response.json()) .then(data => { // Verarbeitung der Mindmap-Daten }); -
Ü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:
-
Überprüfen Sie die Einbindung der JavaScript-Datei:
<script src="{{ url_for('static', filename='js/modules/chatgpt-assistant.js') }}"></script> -
Stellen Sie sicher, dass der Assistent korrekt initialisiert wird:
document.addEventListener('DOMContentLoaded', () => { const assistant = new ChatGPTAssistant(); assistant.initialize(); }); -
Ü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:
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:
# 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:
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:
@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:
# 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:
<!-- In Templates -->
<meta name="csrf-token" content="{{ csrf_token() }}">
🌐 API & AJAX Fehler
7. JSON Parsing Fehler
Fehler: JSONDecodeError: Expecting value
Ursache: Leerer oder ungültiger JSON Body
Lösung:
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:
# 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:
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:
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:
<!-- Versionierung für Cache-Busting -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/social.css') }}?v=2.0">
12. Mobile Responsiveness
Fehler: UI bricht auf mobilen Geräten Ursache: Fehlende Viewport Meta-Tag oder falsche CSS Lösung:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
📁 Datei & Upload Fehler
13. Datei Upload Fehler
Fehler: OSError: [Errno 2] No such file or directory
Ursache: Upload-Verzeichnis existiert nicht
Lösung:
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:
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:
# 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:
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:
// 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:
# 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:
// 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:
@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:
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:
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:
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:
# 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:
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:
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:
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:
# 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:
# 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
# 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:
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:
# 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:
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:
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:
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:
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:
# 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:
-
Eine einzige Query mit IN-Operator verwenden:
# 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) -
Model-Methode anpassen:
# 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) -
API-Endpunkt entsprechend anpassen:
@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