Debugging tanpa metode berubah menjadi tebak-tebakan yang memakan jam. Kabar baiknya: aplikasi Laravel hanya punya segelintir jenis kegagalan yang berulang, dan masing-masing punya urutan diagnosis yang hampir selalu berhasil. Chapter ini menyusun gejala-gejala paling umum menjadi resep baku — mulai dari halaman putih misterius sampai query yang tiba-tiba melambat. Teori exception dan log sudah dibahas di Debugging Laravel ; di sini kita fokus pada alur eksekusinya saat tekanan sedang tinggi.
Pohon Keputusan Diagnosis #
Sebelum mengarang hipotesis, ada dua disiplin kecil yang wajib dipegang: pastikan masalah bisa direproduksi dengan andal (bila hanya terjadi kadang-kadang, catat kondisi persisnya dulu), dan ubah satu hal saja setiap percobaan. Setelah itu, tentukan kategori gejalanya. Diagram berikut merangkum langkah pertama untuk tiap kategori:
Aturan pertamanya sederhana: jangan pernah menebak sebelum membaca log. Log aplikasi Laravel berada di storage/logs/laravel.log dan hampir selalu memuat stack trace lengkap beserta baris kode yang melempar exception. Untuk mengikutinya secara langsung, tail -f storage/logs/laravel.log di terminal, atau gunakan php artisan pail yang menampilkan log berwarna tanpa membuka file.
Resep per Gejala #
| Gejala | Penyebab paling umum | Langkah pertama |
|---|---|---|
| Halaman putih tanpa error | Fatal error sebelum handler aktif | tail laravel.log; cek sintaks file yang baru diubah |
| Error 500 di produksi | Exception apa pun saat APP_DEBUG=false | Reproduksi lokal, atau aktifkan debug sebentar |
| 404 padahal route “sudah ada” | Method/URI tidak cocok, atau route tertimpa | route:list --path=judulnya |
| 419 Page Expired | Token CSRF hilang, sesi/database session mati | Pastikan @csrf; cek SESSION_DRIVER |
| 422 Unprocessable | Validasi gagal — ini bukan bug | Baca errors() di response atau sesi |
| 403/401 padahal “sudah login” | Policy/middleware menolak | Test dengan actingAs; baca policy |
Class "..." not found | Autoloader basi setelah tambah class | composer dump-autoload |
| Migration “tidak jalan” | Belum dijalankan atau gagal diam-diam | php artisan migrate:status |
env('KEY') mengembalikan null | Config sudah di-cache | php artisan config:clear |
Permission denied storage/ | Web server tak bisa menulis | Sesuaikan pemilik folder storage/ |
Empat baris pertama menyangkut request HTTP; empat terakhir menyangkut infrastruktur. Satu baris yang paling sering disalahpahami adalah 422: status ini bukan laporan kegagalan sistem, melainkan cara Laravel mengatakan bahwa validasi menolak input dengan sengaja — jadi perbaikannya ada di data yang dikirim, bukan di server. Mari kita perhatikan resep migration lebih dekat. Perintah migrate:status membandingkan file di database/migrations/ dengan tabel migrations di database — berikut hasil nyatanya di sandbox Course ini:
Migration name .............................................. Batch / Status
0001_01_01_000000_create_users_table ............................... [1] Ran
0001_01_01_000001_create_cache_table ............................... [1] Ran
0001_01_01_000002_create_jobs_table ................................ [1] Ran
2026_10_13_153049_create_personal_access_tokens_table .............. [1] RanBila ada file migration yang tidak muncul di daftar, file tersebut belum pernah dijalankan; bila statusnya Pending, jalankan php artisan migrate. Sebaliknya bila daftar menampilkan migration yang sudah tidak ada filenya, itu tanda skema database dan codebase tidak sinkron — biasanya bekas eksperimen lokal, dan migrate:fresh di environment pengembangan adalah jalan keluarnya.
Query Lambat dan N+1 #
Kategori terakhir berbeda: tidak ada error, hanya halaman yang makin lambat. Tersangka utamanya adalah masalah N+1 — satu query induk diikuti ratusan query relasi di dalam loop, sehingga waktu respons tumbuh seiring jumlah baris. Aktifkan query log sementara untuk menghitungnya:
DB::listen(fn ($q) => print($q->sql . PHP_EOL)); // di tinker atau route debug
Bila daftar query dipenuhi baris select * from users where id = ? yang berulang, solusinya adalah with('penulis') pada query induk — mekanisme eager loading yang dibedah di Optimasi dengan Eager Loading
dan Mencegah N+1
. Untuk halaman yang kompleks namun sudah benar secara query, langkah berikutnya adalah profiling yang dibahas di Profiling Laravel
.
Setelah aplikasi sehat kembali, tantangan berikutnya adalah menjaganya tetap sehat saat dirilis ke server produksi — topik chapter penutup ranah operasional ini: Panduan Deployment .