# Troubleshooting

# 1. "File not found" bei Filesystem-Quellen

Fehlermeldung:

We could not find the file at '/path/to/file.csv' using the disk 'local'.

Ursachen:

  • Der Pfad ist relativ (z.B. imports/file.csv statt /absolute/path/file.csv).
  • Die Datei existiert nicht auf dem konfigurierten Disk.
  • Der Disk ist nicht korrekt in config/filesystems.php konfiguriert.

Lösungen:

  1. Absolute Pfade verwenden:

    ->fromSource(SourceType::FILESYSTEM, ['path' => base_path('storage/app/imports/file.csv')])
  2. Existenz prüfen:

    use Illuminate\Support\Facades\Storage;
    Storage::disk('local')->exists('imports/file.csv'); // true/false
  3. Disk-Konfiguration prüfen:

    // config/filesystems.php
    'disks' => [
        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],
    ],

# 2. Memory-Limit Fehler

Fehlermeldung:

Allowed memory size of 134217728 bytes exhausted

Ursachen:

  • Die CSV/Excel-Datei ist zu groß für das aktuelle memory_limit in PHP.
  • Zu viele Zeilen werden gleichzeitig verarbeitet (z.B. chunkSize zu groß).

Lösungen:

  1. memory_limit erhöhen (in php.ini):

    memory_limit = 512M
  2. Kleinere Chunks verwenden:

    ->setChunkSize(500) // Standard: 100
  3. Transaktionen deaktivieren (für maximale Performance):

    ->transactionMode(TransactionMode::NONE)
  4. Queue-Worker optimieren:

    php artisan queue:work --memory=512

# 3. "Column not found" bei strictHeaders(true)

Fehlermeldung:

The column 'user_email' was not found in the source file headers.

Ursachen:

  • Die Spaltenüberschrift im CSV stimmt nicht mit der Definition in map() oder relate() überein.
  • Groß-/Kleinschreibung oder Leerzeichen unterscheiden sich (z.B. "E-Mail" vs. "email").

Lösungen:

  1. Aliase verwenden:

    ->map(['E-Mail', 'Email', 'user_email'], 'email')
  2. strictHeaders(false) setzen (wenn die Spalte optional ist):

    ->strictHeaders(false)
  3. CSV-Datei anpassen (z.B. mit Excel oder sed):

    # Ersetze Leerzeichen in Headern (Linux/Mac)
    sed -i '1s/ /_/g' input.csv

# 4. "Connection timeout" bei großen Uploads

Fehlermeldung:

Connection timeout or Request timeout exceeded

Ursachen:

  • Die Upload-Zeit überschreitet die PHP max_execution_time.
  • Der Webserver hat eine geringere Timeout-Einstellung.
  • Die Datei ist zu groß für den Upload.

Lösungen:

  1. PHP-Konfiguration anpassen:

    ; php.ini
    max_execution_time = 300
    upload_max_filesize = 100M
    post_max_size = 100M
    max_input_time = 300
  2. Webserver-Timeout erhöhen (nginx Beispiel):

    client_max_body_size 100M;
    proxy_connect_timeout 300;
    proxy_send_timeout 300;
    proxy_read_timeout 300;
  3. Chunked Uploads im Frontend implementieren:

    // Für sehr große Dateien
    const chunkSize = 1024 * 1024; // 1MB chunks
    // Implementieren Sie chunk-by-chunk Upload

# 5. "Queue worker is not running"

Fehlermeldung:

Job failed after maximum attempts

Ursachen:

  • Der Queue-Worker läuft nicht.
  • Der Worker ist abgestürzt oder hat das Zeitlimit überschritten.
  • Queue-Konfiguration ist fehlerhaft.

Lösungen:

  1. Worker starten und überwachen:

    # Starten
    php artisan queue:work
    
    # Mit Supervisord überwachen
    php artisan queue:work --daemon --sleep=1 --tries=3
  2. Supervisor-Konfiguration (/etc/supervisor/conf.d/laravel-worker.conf):

    [program:laravel-worker]
    process_name=%(program_name)s_%(process_num)02d
    command=php /path/to/your/project/artisan queue:work --sleep=3 --tries=3 --max-time=3600
    autostart=true
    autorestart=true
    user=www-data
    numprocs=4
    redirect_stderr=true
    stdout_logfile=/path/to/your/project/storage/logs/worker.log
    stopwaitsecs=3600
  3. Queue-Status prüfen:

    php artisan queue:failed
    php artisan queue:retry all

# 6. "Foreign key constraint violation"

Fehlermeldung:

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row

Ursachen:

  • relate() oder relateMany() kann den referenzierten Datensatz nicht finden.
  • Die referenzierte ID existiert nicht in der Zieltabelle.
  • Die Beziehung ist falsch konfiguriert.

Lösungen:

  1. Debug-Modus für Beziehungen aktivieren:

    ->relate('category_name', 'category', Category::class, 'name', createIfMissing: true)
  2. Datenvalidierung vor dem Import:

    ->beforeRow(function(array &$row) {
        // Prüfen ob Kategorie existiert
        if (!empty($row['category_name'])) {
            $exists = Category::where('name', $row['category_name'])->exists();
            if (!$exists) {
                $row['category_name'] = 'Default Category'; // oder werfen Sie Exception
            }
        }
    })
  3. Fehlende Datensätze erstellen:

    ->relate('category_name', 'category', Category::class, 'name', createIfMissing: true)

# 7. "Invalid datetime format"

Fehlermeldung:

DateTime::__construct(): Failed to parse time string

Ursachen:

  • Das Datumsformat im CSV entspricht nicht dem erwarteten Format.
  • Leere oder ungültige Datumswerte.

Lösungen:

  1. Datumstransformation implementieren:

    ->mapAndTransform('import_date', 'created_at', function($value, $row) {
        if (empty($value)) return null;
    
        // Verschiedene Formate versuchen
        $formats = ['d.m.Y', 'Y-m-d', 'm/d/Y', 'd/m/Y'];
        foreach ($formats as $format) {
            $date = DateTime::createFromFormat($format, $value);
            if ($date !== false) {
                return $date->format('Y-m-d H:i:s');
            }
        }
    
        throw new \InvalidArgumentException("Invalid date format: {$value}");
    })
  2. Flexible Validierung:

    ->validate([
        'import_date' => 'nullable|date_format:d.m.Y|date_format:Y-m-d'
    ])

# 8. Performance ist sehr langsam

Symptome:

  • Import von 10.000 Zeilen dauert mehrere Minuten.
  • Hohe CPU- und Speicher-Auslastung.

Ursachen:

  • Ineffiziente Datenbankabfragen in Hooks.
  • Zu kleine Chunk-Size.
  • Fehlende Indizes in der Datenbank.

Lösungen:

  1. Chunk-Size optimieren:

    ->setChunkSize(1000) // Erhöhen für bessere Performance
  2. Datenbank-Indizes prüfen:

    -- Index für keyedBy Spalte
    CREATE INDEX idx_products_email ON products(email);
    
    -- Fremdschlüssel-Indizes
    CREATE INDEX idx_products_category_id ON products(category_id);
  3. Haken optimieren:

    // ❌ Schlecht: N+1 Queries
    ->afterRow(function($model, $row) {
        $model->category; // Lädt Kategorie für jede Zeile einzeln
    })
    
    // ✅ Gut: Eager Loading
    ->afterRow(function($model, $row) {
        $model->load('category');
    })
  4. Transaktionen optimieren:

    ->transactionMode(TransactionMode::CHUNK)
    ->setChunkSize(500) // Größere Chunks mit Transaktionen

# 9. Debugging-Techniken

# Log-Dateien überprüfen

  1. Laravel Logs:

    tail -f storage/logs/laravel.log
  2. Queue Worker Logs:

    tail -f storage/logs/worker.log
  3. Datenbank-Queries loggen:

    // In AppServiceProvider::boot()
    if (app()->environment('local')) {
        DB::listen(function($query) {
            Log::info($query->sql, $query->bindings);
        });
    }

# Test-Import mit kleinen Datenmengen

  1. Test-CSV erstellen:

    name,email,price
    Test Product,test@example.com,19.99
    Another Product,another@example.com,29.99
  2. Dry-Run durchführen:

    php artisan ingest:run product-importer --file=test.csv --dry-run

# Schritt-für-Schritt-Debugging

->beforeRow(function(array &$row) {
    Log::debug('Processing row', ['row' => $row]);
})
->map('name', 'name')
->map('price', 'price')
->afterRow(function($model, $row) {
    Log::debug('Row processed', ['model_id' => $model->id]);
})

# 10. Häufige Konfigurationsfehler

# Falsche Source-Type-Konfiguration

// ❌ Falsch
->fromSource(SourceType::UPLOAD, ['path' => 'file.csv'])

// ✅ Richtig
->fromSource(SourceType::FILESYSTEM, ['path' => 'file.csv'])
->fromSource(SourceType::UPLOAD) // Keine Parameter für Upload

# Fehlende Berechtigungen

// In Ihrer Policy
public function import(User $user)
{
    return $user->hasPermissionTo('import-products');
}

# Queue-Konfiguration

// config/queue.php
'connections' => [
    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 90, // Wichtig für langlaufende Jobs
        'after_commit' => false,
    ],
],

# Nächste Schritte bei Problemen

  1. Logs prüfen: Überprüfen Sie Laravel- und Worker-Logs
  2. Konfiguration validieren: Stellen Sie sicher, dass alle Pfade und Berechtigungen korrekt sind
  3. Mit kleinen Datenmengen testen: Isolieren Sie das Problem
  4. Datenbank-Performance prüfen: Indizes und Query-Optimierung
  5. Community-Support: Eröffnen Sie ein Issue auf GitHub mit detaillierten Informationen

Für weitere Hilfe besuchen Sie die Dokumentation oder erstellen Sie ein Issue im GitHub Repository.