Bug tidak memandang tingkat pengalaman penulisnya: program yang tadi terasa benar bisa menghasilkan angka yang salah begitu datanya berubah. Yang membedakan bukanlah ada tidaknya bug, melainkan kecepatan menemukannya. Tanpa strategi, proses debug berubah menjadi menebak-nebak dan mengubah kode di banyak tempat sekaligus — kebiasaan yang justru berisiko menambah masalah baru di atas masalah lama.
Chapter ini melatih proses debugging dasar dengan alat yang sudah kita pegang: pesan error, console.log, dan debugger Node/DevTools. Kita berlatih pada satu kasus kecil yang masuk akal: tagihan katering yang terhitung tidak sesuai harapan.
Empat Langkah Melacak Bug #
Proses debugging yang sehat bergerak sistematis dari bukti menuju penyebab:
- Baca pesan error sampai tuntas. Node dan browser menyebut jenis error, pesannya, dan posisinya (berkas serta baris). Pesan itu adalah titik awal, bukan gangguan yang perlu diabaikan.
- Perkecil wilayah. Tentukan bagian mana yang keliru: apakah datanya, perhitungannya, atau bagian yang menampilkannya.
- Amati nilai antara. Pasang
console.logberlabel di titik-titik kunci, lalu bandingkan nilai yang tampil dengan nilai yang seharusnya. - Perbaiki satu hal, lalu verifikasi. Jalankan ulang dan bandingkan hasilnya dengan harapan yang dituliskan sejak awal.
Kasus berikut menuntun kita melewati langkah ketiga sampai keempat.
console.log Terstruktur #
console.log bisa dipakai begitu saja, tetapi log yang berhamburan tanpa label justru membingungkan: kita tidak tahu angka mana milik variabel mana. Prinsip sederhananya: satu nilai per baris, selalu disertai label, dengan format yang konsisten (nama : nilai). Berkas berikut menerapkannya pada kasus tagihan katering yang hasilnya dicurigai:
// lacak-bug.js
// Tagihan katering tidak sesuai harapan. Kita perangkap setiap nilai antara
// dengan console.log berlabel agar penyimpangan langsung terlihat.
const jumlahPorsi = 8;
const hargaPerPorsi = 25000;
const biayaAntar = 15000;
const persenDiskon = 20;
let subtotal = jumlahPorsi * hargaPerPorsi;
let potongan = subtotal / persenDiskon; // terindikasi keliru
let total = subtotal - potongan + biayaAntar;
console.log("--- nilai antara ---");
console.log("jumlahPorsi :", jumlahPorsi);
console.log("hargaPerPorsi :", hargaPerPorsi);
console.log("subtotal :", subtotal);
console.log("potongan :", potongan);
console.log("biayaAntar :", biayaAntar);
console.log("total :", total);Output yang Dihasilkan:
--- nilai antara ---
jumlahPorsi : 8
hargaPerPorsi : 25000
subtotal : 200000
potongan : 10000
biayaAntar : 15000
total : 205000Mari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 5–8 (
const jumlahPorsi = 8;dst.): input masalah disimpan sebagai konstanta bernama — pembaca langsung tahu nilai mana yang menjadi data awal. - Baris 10 (
let subtotal = jumlahPorsi * hargaPerPorsi;): langkah perhitungan pertama. Nilainya kelak bisa diverifikasi dengan hitungan tangan. - Baris 11 (
let potongan = subtotal / persenDiskon;): baris yang keliru — kita akan melihat buktinya dari keluaran, bukan dari tebakan. - Baris 12 (
let total = subtotal - potongan + biayaAntar;): langkah akhir yang menggabungkan hasil dua baris sebelumnya; jika salah satu sumbernya keliru, nilai ini ikut salah. - Baris 14 (
console.log("--- nilai antara ---");): penanda pembatas keluaran sehingga blok log mudah dikenali di antara keluaran program lain. - Baris 15–20 (
console.log("jumlahPorsi :", jumlahPorsi);dst.): enam log berlabel dengan lebar label yang rata. Format sejajar ini membuat mata cepat membandingkan baris demi baris.
Membaca Bukti dari Keluaran #
Sekarang kita bekerja seperti detektif, membandingkan setiap nilai dengan harapan:
subtotal : 200000— sesuai dugaan, karena8 * 25000 = 200000.potongan : 10000— tidak sesuai. Diskon 20% dari 200.000 seharusnya40000.total : 205000— nilai akhir ikut menyimpang karena mewarisipotonganyang keliru.
Bukti menunjuk satu baris: subtotal / persenDiskon membagi subtotal dengan angka 20, padahal maksud kita adalah menghitung 20% dari subtotal. Perbaikannya mengubah pola perhitungan menjadi kali dulu, baru bagi seratus:
let subtotal = jumlahPorsi * hargaPerPorsi;
let potongan = subtotal * persenDiskon / 100; // 20% dari subtotal
let total = subtotal - potongan + biayaAntar;
console.log("potongan :", potongan);
console.log("total :", total);Output yang Dihasilkan:
potongan : 40000
total : 175000Kedua nilai kini cocok dengan hitungan tangan: 200000 * 20 / 100 = 40000, dan 200000 - 40000 + 15000 = 175000. Pola subtotal * persenDiskon / 100 dievaluasi kiri ke kanan (* dan / setara, dibaca berurutan) sehingga hasilnya sesuai maksud.
Breakpoint: Menghentikan Program di Titik Tertentu #
console.log hampir selalu cukup untuk kode kecil, tetapi debugger menyediakan cara yang lebih tajam: menghentikan program persis di satu baris, lalu mengamati seluruh keadaan program saat itu — bukan hanya nilai yang kita ingat untuk dicatat.
Untuk kode Node, gunakan flag --inspect:
node --inspect lacak-bug.jsPerintah tersebut tidak menampilkan hasil program untuk dibandingkan; program justru menunggu koneksi debugger, dan keluarannya berupa URL WebSocket yang siap dihubungi. Cara menyambungkannya:
- Buka Chrome, ketik
chrome://inspectdi address bar, lalu pilih perangkat/proses Node yang terdeteksi. - Klik inspect — jendela DevTools terbuka dengan panel Sources yang memuat kode
lacak-bug.js. - Klik nomor baris yang dicurigai (misalnya baris 11) untuk memasang breakpoint — tanda biru pada nomor baris itu.
- Muat ulang program (tombol ikon reload di panel Sources, atau jalankan ulang perintah
node --inspect). Eksekusi berhenti tepat sebelum baris breakpoint. - Di panel Scope, semua variabel yang hidup pada titik itu tampil beserta nilainya; panel Watch bisa diisi ekspresi pilihan, misalnya
subtotal * persenDiskon / 100, untuk membandingkan dugaan dan fakta. - Lanjutkan eksekusi baris demi baris dengan tombol Step over next function call (F10) dan amati nilai mana yang berubah.
Untuk script yang berjalan di browser, jalur yang sama tersedia tanpa flag apa pun: buka DevTools (F12), pindah ke tab Sources, klik nomor baris untuk memasang breakpoint, lalu muat ulang halaman agar breakpoint terpicu. Ada juga statement debugger; — menuliskannya di dalam kode berfungsi seperti breakpoint yang tertanam; eksekusi berhenti di situ hanya ketika DevTools terbuka.
Perangkat di chapter ini — pesan error, log terstruktur, dan breakpoint — akan terus dipakai sepanjang course, dan diperdalam di section Error Handling. Keahliannya tumbuh lewat latihan: setiap kali program tidak sesuai harapan, jangan langsung mengubah kode; bukti dulu, penyebab belakangan.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
lacak-bug.js
Unduh berkas// lacak-bug.js
// Tagihan katering tidak sesuai harapan. Kita perangkap setiap nilai antara
// dengan console.log berlabel agar penyimpangan langsung terlihat.
const jumlahPorsi = 8;
const hargaPerPorsi = 25000;
const biayaAntar = 15000;
const persenDiskon = 20;
let subtotal = jumlahPorsi * hargaPerPorsi;
let potongan = subtotal / persenDiskon; // terindikasi keliru
let total = subtotal - potongan + biayaAntar;
console.log("--- nilai antara ---");
console.log("jumlahPorsi :", jumlahPorsi);
console.log("hargaPerPorsi :", hargaPerPorsi);
console.log("subtotal :", subtotal);
console.log("potongan :", potongan);
console.log("biayaAntar :", biayaAntar);
console.log("total :", total);