Episode ini membahas strategi menangani error di Node.js: try/catch, error-first callback, event error dari EventEmitter, serta best practice untuk uncaughtException. Kalian juga belajar debugging dengan Node Inspector dan DevTools.

Kode yang tidak pernah error hanya ada di imajinasi. Yang membedakan pengembang senior adalah cara mereka menangani error: mencegah crash, mencatat jejak yang berguna, dan memperbaiki akar masalah dengan cepat. Node.js punya pola error khas yang harus kalian kenali.
Episode 6 membahas empat lapis penanganan error di Node.js: try/catch untuk Promise, pola error-first untuk callback, event error dari EventEmitter, dan penanganan error global. Di paruh kedua, kita masuk ke debugging dengan Node Inspector dan Chrome DevTools.
Sejak kita memakai Promise (episode 5), try/catch menjadi alat utama:
import { readFile } from "node:fs/promises";
try {
const isi = await readFile("tidak-ada.txt", "utf8");
console.log(isi);
} catch (err) {
console.error("Gagal membaca:", err.code);
}Ketika await menghasilkan error, alur melompat ke blok catch dan err berisi detail seperti code dengan nilai ENOENT. Membaca err.code jauh lebih andal daripada mem-parsing pesan teks — gunakan kode error untuk logika percabangan.
API callback lawas di Node.js memakai konvensi error-first: argumen pertama callback selalu error, atau null jika sukses:
import { readFile } from "node:fs";
readFile("tidak-ada.txt", "utf8", (err, data) => {
if (err) {
console.error("Terjadi error:", err.message);
return;
}
console.log(data);
});Pola (err, data) => ... memaksa kalian memeriksa err terlebih dahulu. Konvensi ini masih ditemui di paket-paket lawas, jadi memahami polanya penting meskipun project baru memakai Promise.
Objek berbasis EventEmitter — seperti stream, server HTTP, dan request — menangani error melalui event khusus bernama error. Jika tidak ada listener untuk event ini, Node.js melempar error dan menghentikan proses:
import { EventEmitter } from "node:events";
const emitter = new EventEmitter();
emitter.on("error", (err) => {
console.error("Terjadi error:", err.message);
});
emitter.emit("error", new Error("koneksi gagal"));Pola emitter.on("error", (err) => ...) menangkap error yang dikirim. Aturan penting: selalu pasang listener error pada objek EventEmitter di aplikasi kalian, terutama stream dan server, karena error tanpa listener akan menghentikan seluruh proses.
Dua jenis error bisa lolos dari penanganan lokal: exception yang tidak tertangkap (uncaughtException) dan Promise yang gagal tanpa catch (unhandledRejection). Keduanya memicu peristiwa global:
process.on("uncaughtException", (err) => {
console.error("Uncaught exception:", err);
process.exit(1);
});
process.on("unhandledRejection", (reason) => {
console.error("Unhandled rejection:", reason);
});Praktik terbaik untuk uncaughtException: catat errornya, lalu keluar. Proses dengan state yang tidak konsisten tidak bisa dipercaya lagi, dan meneruskan berjalan justru berbahaya. Pastikan ada process manager yang me-restart aplikasi — kita akan membahasnya di episode 21 dan 22.
Jangan abaikan exit code. Script yang sukses keluar dengan kode 0, sementara error menggunakan kode bukan nol:
node app.js
echo "Exit code: $?"Setelah node app.js, variabel $? di shell menampung exit code perintah terakhir. CI/CD memakai nilai ini untuk menentukan apakah build gagal — kita akan memakainya lagi di episode 18.
Node.js menyertakan debugger bawaan berbasis protokol Chrome DevTools. Jalankan aplikasi dengan flag inspector, lalu buka DevTools di browser:
node --inspect app.jsnode --inspect app.js membuat proses mendengarkan di port 9220 dan menampilkan URL chrome://inspect. Buka halaman tersebut di Chrome, klik proses Node.js kalian, dan kalian mendapat panel lengkap: breakpoint, watch expression, call stack, dan evaluasi ekspresi langsung.
Untuk berhenti di baris pertama program, pakai --inspect-brk:
node --inspect-brk app.jsDengan node --inspect-brk app.js, eksekusi berhenti di awal sehingga kalian bisa menelusuri kode langkah demi langkah. Alternatif tanpa browser: node inspect app.js memberi debugger di terminal dengan perintah seperti cont, next, step, dan repl.
Untuk masalah sederhana, console.log tetap alat paling cepat. Namun bedakan levelnya: console.log untuk info, console.warn untuk peringatan, dan console.error untuk error. Di episode 12 kita akan menggantinya dengan logging terstruktur yang siap produksi.
Inti yang harus dibawa pulang:
try/catch untuk Promise dan async/await.err di awal.error pada objek EventEmitter.uncaughtException harus dicatat lalu keluar dari proses.--inspect dan --inspect-brk membuka debugging penuh via Chrome DevTools.Di episode 7 selanjutnya kita akan membahas membuat server HTTP sederhana dengan modul http — createServer, membaca method dan URL dari request, mengirim response dengan status dan header, serta menguji server dengan curl. Inilah momen Node.js benar-benar menjadi backend.