Files
website/COMMON_ERRORS.md

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:

  1. 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")
    
  2. 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])
    
  3. 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_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:

    # 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):

    # 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:

    # 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:

    @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:

    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:

  1. 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()
    
  2. 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:

  1. 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'))
    
  2. 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:

  1. 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
    
  2. 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
    
  3. 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() 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

    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

    python create_default_users.py
    

    Dieses Skript:

    • Erstellt Standardbenutzer (admin, user), falls keine vorhanden sind
    • Setzt Passwörter mit korrektem Hashing
  3. Datenbank testen

    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:

    <link href="https://cdn.tailwindcss.com" rel="stylesheet">
    
  2. Überprüfen Sie die Netzwerkverbindung und ob die CDN-Domains erreichbar sind.

  3. 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:

  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:

    # 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:

    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
    <script src="{{ url_for('static', filename='js/alpine.min.js') }}" defer></script>
    
  4. 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:

  1. Verwenden Sie die lokale Version von Tailwind CSS:

    <link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
    
  2. Alternativ können Sie die CDN-Version direkt im Template einbinden:

    <script src="https://cdn.tailwindcss.com"></script>
    
  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:

    <script src="{{ url_for('static', filename='neural-network-background.js') }}"></script>
    
  2. Initialisieren Sie die Animation im Template:

    <script>
      document.addEventListener('DOMContentLoaded', () => {
        const background = new NeuralNetworkBackground();
        background.initialize();
        background.animate();
      });
    </script>
    
  3. 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:

  1. Überprüfen Sie die API-Endpunkte für die Mindmap-Daten:

    @app.route('/api/mindmap/nodes', methods=['GET'])
    def get_mindmap_nodes():
        # Implementierung...
    
  2. Stellen Sie sicher, dass die AJAX-Anfragen korrekt implementiert sind:

    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:

    <script src="{{ url_for('static', filename='js/modules/chatgpt-assistant.js') }}"></script>
    
  2. Stellen Sie sicher, dass der Assistent korrekt initialisiert wird:

    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:

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:

  1. 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)
    
  2. 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)
    
  3. 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

SQLAlchemy Beziehungsfehler