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.jsondie 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 = Ordnername8.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:
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 methodsLösung: Implementieren Sie alle abstrakten Methoden von UebungBase:
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:
- Prüfen Sie den Pfad in der
config.json:
"create": {
"path": "resources/vue/UebungVokabeltrainerCreateComponent.vue",
"alias": "uebung-vokabeltrainer-create-component"
}- Stellen Sie sicher, dass die Komponente existiert und korrekt exportiert wird:
<script>
export default {
name: "uebung-vokabeltrainer-create-component" // Muss mit alias übereinstimmen
}
</script>- Cache leeren:
php artisan cache:clear
php artisan view:clear
npm run dev8.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:
// 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:
- Prüfen Sie die Route-Syntax:
// Falsch
axios.post('/api/uebungen/store/uebung-vokabeltrainer')
// Richtig (mit haxiosAPIClient)
haxiosAPIClient.post('/uebungen/store/uebung-vokabeltrainer')- Stellen Sie sicher, dass die Daten im richtigen Format gesendet werden:
// 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 existsLösung:
- Prüfen Sie, ob die Tabelle bereits existiert:
php artisan db:show- Bei Bedarf Migration rollback:
php artisan migrate:rollback --step=1- Verwenden Sie Conditional Creates:
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:
- Cast in Model definieren:
protected $casts = [
'content_data' => 'array'
];- In der
config.jsonkorrekt definieren:
"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:
"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:
"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:
- Eager Loading verwenden:
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:
// Backend
Log::info('UebungVokabeltrainer::storeUebung', [
'data' => $data,
'user' => auth()->id()
]);// 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:
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:
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'
]);
}
}