Skip to content

8. How To - Troubleshooting und Pitfalls

Bei der Entwicklung von Übungsmodulen können verschiedene Probleme auftreten. Dieser Abschnitt hilft Ihnen, häufige Fehler zu vermeiden und Probleme schnell zu lösen.

8.1 Häufige Fehlerquellen

8.1.1 Namenskonventionen nicht eingehalten

Problem: Die Übung wird nicht in der UebungenRegistry registriert oder wirft Fehler.

Symptome:

InvalidArgumentException: Der Alias in der config.json muss den Kebab-Case-Namen des Moduls haben.

Lösung: Stellen Sie sicher, dass:

  • Der Modulordner im PascalCase benannt ist: UebungVokabeltrainer
  • Der Alias in der config.json die Kebab-Case-Version ist: uebung-vokabeltrainer
  • Das Model denselben Namen wie der Modulordner hat

Richtig:

modules/Uebungen/UebungVokabeltrainer/          # Ordnername
├── config.json (alias: "uebung-vokabeltrainer") # Kebab-Case
└── app/Models/UebungVokabeltrainer.php         # Model-Name = Ordnername

8.1.2 Trait-Implementierung vergessen

Problem: Die UebungenAPI wirft Fehler bei bestimmten Operationen.

Symptome:

InvalidArgumentException: Die Klasse definiert in der config.json 'is_timetrackable' = true und muss daher den Trait Timetrackable implementieren.

Lösung: Wenn Sie in der config.json eine Option aktivieren, müssen Sie den entsprechenden Trait implementieren:

php
use App\ServiceClasses\Uebungen\UebungenAPI\Traits\PropertyTraits\Timetrackable;
use App\ServiceClasses\Uebungen\UebungenAPI\Traits\PropertyTraits\Absolvable;
use App\ServiceClasses\Uebungen\UebungenAPI\Traits\PropertyTraits\Rewardable;

class UebungVokabeltrainer extends UebungBase 
{
    use Timetrackable;  // Wenn is_timetrackable: true
    use Absolvable;     // Wenn is_absolvable: true
    use Rewardable;     // Wenn is_rewardable: true
}

8.1.3 Fehlende Methodenimplementierung

Problem: PHP Fatal Error beim Aufruf einer Übungsoperation.

Symptome:

Error: Class UebungVokabeltrainer contains 1 abstract method and must therefore be declared abstract or implement the remaining methods

Lösung: Implementieren Sie alle abstrakten Methoden von UebungBase:

php
public function storeUebung(array $data, Request $request = null): static { }
public function updateUebung(array $data, Request $request = null): static { }
public function deleteUebung(Request $request = null): static { }
public function printUebung(Request $request = null): mixed { }
public function shareUebung(Request $request = null): mixed { }
public function showUebung(Request $request = null): mixed { }
public function previewUebung(Request $request = null): mixed { }
public function absolveUebung(Request $request = null): mixed { }
public function evaluateUebung(Request $request = null): mixed { }

8.2 Frontend-Probleme

8.2.1 Komponente wird nicht gefunden

Problem: Die Vue-Komponente wird nicht geladen.

Symptome:

[Vue warn]: Unknown custom element: <uebung-vokabeltrainer-create-component>

Lösung:

  1. Prüfen Sie den Pfad in der config.json:
json
"create": {
    "path": "resources/vue/UebungVokabeltrainerCreateComponent.vue",
    "alias": "uebung-vokabeltrainer-create-component"
}
  1. Stellen Sie sicher, dass die Komponente existiert und korrekt exportiert wird:
vue
<script>
export default {
    name: "uebung-vokabeltrainer-create-component"  // Muss mit alias übereinstimmen
}
</script>
  1. Cache leeren:
bash
php artisan cache:clear
php artisan view:clear
npm run dev

8.2.2 Store-Daten werden nicht aktualisiert

Problem: Änderungen im Pinia Store werden nicht in den Komponenten reflektiert.

Lösung: Verwenden Sie die richtige Syntax für Pinia:

javascript
// Falsch
this.store.uebung = newData;

// Richtig
this.store.setUebung(newData);

// Oder für einzelne Properties
this.store.$patch({
    uebung: {
        title: 'Neuer Titel'
    }
});

8.2.3 API-Calls schlagen fehl

Problem: 404 oder 500 Fehler bei API-Aufrufen.

Lösung:

  1. Prüfen Sie die Route-Syntax:
javascript
// Falsch
axios.post('/api/uebungen/store/uebung-vokabeltrainer')

// Richtig (mit haxiosAPIClient)
haxiosAPIClient.post('/uebungen/store/uebung-vokabeltrainer')
  1. Stellen Sie sicher, dass die Daten im richtigen Format gesendet werden:
javascript
// Die UebungenAPI erwartet Daten im 'data' Objekt
haxiosAPIClient.post('/uebungen/store/uebung-vokabeltrainer', {
    data: {
        title: 'Titel',
        description: 'Beschreibung',
        content_data: []
    }
})

8.3 Datenbank-Probleme

8.3.1 Migration schlägt fehl

Problem: Fehler beim Ausführen der Migration.

Symptome:

SQLSTATE[42S01]: Base table or view already exists

Lösung:

  1. Prüfen Sie, ob die Tabelle bereits existiert:
bash
php artisan db:show
  1. Bei Bedarf Migration rollback:
bash
php artisan migrate:rollback --step=1
  1. Verwenden Sie Conditional Creates:
php
if (!Schema::hasTable('uebung_vokabeltrainer')) {
    Schema::create('uebung_vokabeltrainer', function (Blueprint $table) {
        // ...
    });
}

8.3.2 JSON-Felder werden nicht korrekt gespeichert

Problem: content_data wird als String statt als JSON gespeichert.

Lösung:

  1. Cast in Model definieren:
php
protected $casts = [
    'content_data' => 'array'
];
  1. In der config.json korrekt definieren:
json
"content_data": {
    "type": "json",
    "casts": {
        "from_db": "array",
        "to_db": "json"
    }
}

8.4 Validierungsprobleme

8.4.1 Validierung wird nicht ausgeführt

Problem: Ungültige Daten werden trotzdem gespeichert.

Lösung: Stellen Sie sicher, dass die Validierung in der config.json aktiviert ist:

json
"fields": {
    "title": {
        "validation": {
            "is_enabled": true,  // Muss true sein!
            "rules": "required|string|min:3"
        }
    }
}

8.4.2 Validierungsmeldungen werden nicht angezeigt

Problem: Bei Validierungsfehlern erscheinen keine spezifischen Meldungen.

Lösung: Definieren Sie Nachrichten für jede Regel:

json
"validation": {
    "is_enabled": true,
    "rules": "required|string|min:3",
    "messages": {
        "de": {
            "required": "Dieses Feld ist erforderlich.",
            "string": "Dieses Feld muss Text enthalten.",
            "min": "Mindestens 3 Zeichen erforderlich."
        }
    }
}

8.5 Performance-Probleme

8.5.1 Langsame Ladezeiten

Problem: Die Übung lädt sehr langsam.

Lösungsansätze:

  1. Eager Loading verwenden:
php
public function showUebung(Request $request = null): mixed
{
    return $this->load(['lerneinheit', 'user']);
}

8.6 Debugging-Tipps

8.6.1 Browser-Konsole

Nutzen Sie Vue DevTools und überprüfen Sie:

  • Komponenten-Props
  • Store-Status
  • Event-Emissions

8.6.2 Log-Ausgaben

Fügen Sie strategische Log-Ausgaben ein:

php
// Backend
Log::info('UebungVokabeltrainer::storeUebung', [
    'data' => $data,
    'user' => auth()->id()
]);
javascript
// Frontend
console.log('Store state:', this.store.$state);

8.7 Testing des Übungsmoduls

8.7.1 Unit Tests für das Model

Erstellen Sie Tests für alle wichtigen Methoden:

php
namespace Tests\Unit\Modules\Uebungen\UebungVokabeltrainer;

use Tests\TestCase;
use Modules\Uebungen\UebungVokabeltrainer\app\Models\UebungVokabeltrainer;

class UebungVokabeltrainerTest extends TestCase
{
    public function test_can_create_uebung()
    {
        $data = [
            'title' => 'Test Vokabeltrainer',
            'description' => 'Eine Testbeschreibung',
            'content_data' => [
                ['value_given' => 'test', 'value_expected' => 'Test']
            ]
        ];
        
        $uebung = (new UebungVokabeltrainer())->storeUebung($data);
        
        $this->assertInstanceOf(UebungVokabeltrainer::class, $uebung);
        $this->assertEquals('Test Vokabeltrainer', $uebung->title);
    }
    
    public function test_validates_required_fields()
    {
        $this->expectException(ValidationException::class);
        
        $data = [
            // title fehlt - sollte Validierungsfehler werfen
            'description' => 'Beschreibung'
        ];
        
        (new UebungVokabeltrainer())->storeUebung($data);
    }
}

8.7.2 Feature Tests für API-Endpunkte

Testen Sie die Integration mit der UebungenAPI:

php
namespace Tests\Feature\Modules\Uebungen\UebungVokabeltrainer;

use Tests\TestCase;
use App\Models\User;

class UebungVokabeltrainerApiTest extends TestCase
{
    protected User $user;
    
    protected function setUp(): void
    {
        parent::setUp();
        $this->user = User::factory()->create();
    }
    
    public function test_can_store_via_api()
    {
        $response = $this->actingAs($this->user)
            ->postJson('/api/uebungen/store/uebung-vokabeltrainer', [
                'data' => [
                    'title' => 'API Test',
                    'description' => 'Test via API',
                    'content_data' => []
                ]
            ]);
        
        $response->assertStatus(200)
            ->assertJsonStructure([
                'data' => ['uebung'],
                'messages',
                'status'
            ]);
    }
}