Berdasarkan fondasi yang kuat sekalipun, aplikasi tetap sesekali berperilaku di luar dugaan: server mendadak diam, berkas yang “jelas ada” dilaporkan hilang, atau await tidak pernah kembali. Debugging adalah keterampilan tersendiri, dan keterampilan itu mempunyai metode — bukan sekadar menabur console.log sambil berharap kebetulan. Chapter ini adalah halaman rujukan untuk momen-momen tersebut: cara membaca pesan error sampai tuntas, tabel pemetaan gejala umum ke penyebab dan langkah pemeriksaannya, daftar alat bawaan, serta urutan kerja yang teratur. Semua rujukan menunjuk ke chapter Course yang membahas akar masalahnya secara mendalam.
Membaca Pesan Error Secara Utuh #
Error Node.js datang dalam dua keluarga yang perlu dibedakan karena tempat mencarinya berbeda:
| Keluarga | Pola nama | Contoh | Daftar resmi |
|---|---|---|---|
| Error sistem | Kapital tanpa awalan, warisan sistem operasi | ENOENT, ECONNREFUSED, EADDRINUSE | Bagian Common System Errors pada halaman errors referensi API |
| Error internal Node.js | Berawalan ERR_ | ERR_MODULE_NOT_FOUND, ERR_INVALID_ARG_TYPE | Indeks kode error pada halaman errors yang sama |
Error sistem membawa properti tambahan yang mempersempit pencarian. Berkas baca-error.mjs berikut memicu error sistem secara sengaja lalu mencetak seluruh properti pentingnya:
import { readFile } from "node:fs/promises";
// Memicu error sistem secara sengaja: berkas ini memang tidak ada
try {
await readFile("tidak-ada.txt", "utf8");
} catch (e) {
console.log(`name : ${e.name}`);
console.log(`code : ${e.code}`);
console.log(`errno : ${e.errno}`);
console.log(`syscall : ${e.syscall}`);
console.log(`path : ${e.path}`);
}Output yang Dihasilkan:
name : Error
code : ENOENT
errno : -2
syscall : open
path : tidak-ada.txtMari kita telaah properti yang tercetak:
code(ENOENT): kode paling penting untuk dicari; artinya no such file or directory — target tidak ditemukan.errno(-2): nomor error sistem operasi; nilainya berbeda-beda antar platform, jadicodeselalu lebih aman dipakai dalam kode.syscall(open): operasi sistem yang sedang berjalan ketika kegagalan terjadi — di sini proses sedang membuka berkas.path(tidak-ada.txt): target yang diminta apa adanya, termasuk bila ia berupa path relatif; membandingkannya dengan isi folder sering langsung menyingkap salah ketik.
Keluarga ERR_ juga bisa diperiksa dengan pola yang sama. Snippet berikut mencoba mengimpor module yang tidak ada dan mencetak hanya kodenya:
try {
const modul = await import("./tidak-ada.mjs");
console.log(modul);
} catch (e) {
console.log(`code : ${e.code}`);
}Output yang Dihasilkan:
code : ERR_MODULE_NOT_FOUNDTabel Gejala Umum #
Tabel berikut memetakan gejala yang paling sering dijumpai sepanjang Course ke dugaan penyebab, langkah pemeriksaan, dan chapter yang membahas akar masalahnya. Gunakan sebagai titik awal, bukan putusan akhir:
| Gejala | Kemungkinan penyebab | Langkah pemeriksaan | Rujukan chapter |
|---|---|---|---|
| Server berhenti merespons seluruh permintaan | Event loop terblokir operasi sinkron yang berat di dalam handler | Periksa handler terakhir yang menangani permintaan; profil proses; pindahkan beban CPU ke worker | Event Loop, Worker Threads, Profiling CPU dan Heap |
ERR_MODULE_NOT_FOUND saat aplikasi dinyalakan | Path relatif salah, ekstensi berkas terlewat pada ESM, atau dependency belum terpasang | Bandingkan specifier import dengan aturan resolusi; jalankan npm install; periksa package.json | Resolusi Module, npm dan Dependencies |
ECONNREFUSED dari klien HTTP atau TCP | Server tujuan belum berjalan, atau alamat dan port salah | Cocokkan host dan port; pastikan listen() berhasil sebelum klien menghubungi | Membangun TCP Client, HTTP Client dengan fetch |
EADDRINUSE saat listen() | Port masih dipakai proses lain | Hentikan proses lama atau pilih port lain; pasang handler 'error' pada server untuk memutuskan strategi | Membangun TCP Server |
ENOENT untuk berkas yang terasa sudah ada | Path relatif dihitung dari current working directory, bukan lokasi berkas kode | Cetak process.cwd() dan bandingkan; bangun path absolut dari import.meta.url | Membaca Berkas, Module path |
await menggantung tanpa hasil | Jalur resolve/reject tidak pernah tercapai, atau event yang dijanjikan tidak pernah terbit | Audit setiap cabang kode agar selalu menyelesaikan promise; pastikan emitter masih hidup | Promise dan async-await, Promise untuk Tugas Paralel |
| Proses berhenti karena unhandled rejection | Rantai promise ditolak tanpa catch di salah satu cabang | Tambahkan catch pada rantai; pasang pemantau unhandledRejection untuk mencatat sebelum keluar | Error pada Kode Asynchronous |
| Callback tidak pernah dipanggil | Cabang penanganan error lupa memanggil callback-nya | Audit semua cabang function async; terapkan konvensi error-first secara konsisten | Pola Callback |
| Perilaku berbeda antara mesin kantor dan server | Environment variable tidak terbaca atau bernilai berbeda | Cetak daftar kunci process.env; jalankan dengan --env-file agar konfigurasi eksplisit | Environment Variables, Konfigurasi Aplikasi |
| Hasil async berubah antar eksekusi | Urutan operasi paralel tidak ditentukan sehingga terjadi race condition | Rangkai ketergantungan antar langkah dengan await; jangan berasumsi urutan selesai | Promise untuk Tugas Paralel |
Alat Bawaan untuk Menyelidiki #
Setelah gejala terpetakan, Node.js menyediakan beberapa alat tanpa instalasi tambahan. Panduan resmi Debugging Node.js menjelaskan keseluruhannya; berikut ringkasan perannya:
| Alat | Kegunaan | Rujukan chapter |
|---|---|---|
node --inspect | Menyambungkan inspector untuk menjeda eksekusi, memeriksa variabel, dan melangkah baris demi baris | Debugging dengan node –inspect |
Modul node:inspector | Mengendalikan sesi debugging lewat program | Debugging dengan node –inspect |
| Stack trace | Membaca urutan pemanggilan yang berujung pada error | Membaca Stack Trace |
console.error dan console.table | Mencatat ke kanal stderr dan menabulasikan data saat menyelidiki | Teknik Logging, stdin, stdout, dan stderr |
node --watch | Menjalankan ulang otomatis saat berkas berubah, mempercepat siklus cek-perbaiki | Watch Mode |
Urutan Kerja yang Teratur #
Saat gejala belum jelas termasuk baris mana pun di tabel, kembalikan diri ke urutan kerja yang sederhana namun disiplin:
- Bangkitkan ulang secara andal. Gejala yang hanya muncul kadang-kadang perlu dikecilkan dulu menjadi langkah-langkah yang selalu memunculkannya.
- Baca pesan error sampai habis — kode,
syscall, dan baris pertama stack trace — sebelum menyusun dugaan apa pun. - Persempit wilayah salah dengan mengomentari atau melewati bagian kode, memakai git untuk membandingkan versi yang masih sehat, atau
console.logyang ditempatkan strategis di batas-batas lapisan. - Uji satu dugaan pada satu waktu. Mengubah banyak hal sekaligus membuat kita tidak tahu mana yang benar-benar berpengaruh.
- Perbaiki, lalu kunci dengan test. Test regresi memastikan gejala yang sama tidak kembali diam-diam — materinya ada pada Chapter Konsep Testing.
Dengan peta ini, mayoritas kejadian sehari-hari bisa dipersempit ke satu penyebab dalam beberapa langkah pemeriksaan. Sebagian kecil sisanya menuntut ketelitian dari sisi lain: aplikasi yang benar secara logika tetap bisa bocor jika dihadapkan pada pihak yang sengaja mencari celah — itulah medan Chapter Panduan Keamanan.