menengaherrorclassMenengah3 mnt baca

Custom Error: Membuat Jenis Error Sendiri

throw new Error("gagal") memang bisa dipakai di mana saja, tapi semua error jadi terlihat sama. Bagaimana kalau kode kamu perlu membedakan "user tidak ditemukan" dengan "koneksi database putus"? Di sinilah custom erro...

Custom Error: Membuat Jenis Error Sendiri

throw new Error("gagal") memang bisa dipakai di mana saja, tapi semua error jadi terlihat sama. Bagaimana kalau kode kamu perlu membedakan "user tidak ditemukan" dengan "koneksi database putus"? Di sinilah custom error class berperan.

Kenapa custom error ada

Di aplikasi nyata, penanganan error tidak boleh seragam. Kalau login gagal karena password salah, tampilkan pesan "password salah". Kalau gagal karena server mati, tampilkan "coba lagi nanti". Kalau semua error hanya bertuliskan "Error: gagal", kode kamu tidak bisa memutuskan respons yang tepat. Custom error memberi setiap jenis masalah identitasnya sendiri, sehingga blok catch bisa bereaksi secara spesifik dengan instanceof.

Membuat class error sendiri

Caranya sederhana: buat class yang extends Error, lalu atur name-nya:

javascript
class ValidasiError extends Error {
  constructor(pesan) {
    super(pesan);
    this.name = "ValidasiError";
  }
}

function daftar(nama, umur) {
  if (!nama) throw new ValidasiError("Nama wajib diisi");
  if (umur < 13) throw new ValidasiError("Umur minimal 13 tahun");
  return { nama, umur };
}

try {
  daftar("", 10);
} catch (error) {
  if (error instanceof ValidasiError) {
    console.log("Kesalahan input:", error.message);
  } else {
    console.log("Kesalahan tak terduga:", error.message);
  }
}

super(pesan) memanggil constructor Error sehingga message dan stack trace terisi otomatis. Tanpa super, class-nya rusak. Properti name membuat pesan error terbaca jelas: "ValidasiError: Nama wajib diisi" bukan sekadar "Error".

Contoh realistis: error bertingkat di aplikasi warung

Aplikasi kasir butuh pesan berbeda untuk masalah berbeda. Satu class induk, beberapa class anak:

javascript
class KasirError extends Error {
  constructor(pesan) {
    super(pesan);
    this.name = "KasirError";
  }
}

class StokHabisError extends KasirError {
  constructor(namaProduk) {
    super(`Stok ${namaProduk} habis`);
    this.name = "StokHabisError";
    this.produk = namaProduk;
  }
}

class BayarKurangError extends KasirError {
  constructor(kurang) {
    super(`Uang kurang Rp${kurang}`);
    this.name = "BayarKurangError";
    this.kurang = kurang;
  }
}

function prosesBayar(produk, uangDiberikan) {
  if (produk.stok === 0) throw new StokHabisError(produk.nama);
  if (uangDiberikan < produk.harga) {
    throw new BayarKurangError(produk.harga - uangDiberikan);
  }
  return "Pembayaran berhasil";
}

try {
  prosesBayar({ nama: "Kopi Susu", harga: 8000, stok: 0 }, 10000);
} catch (error) {
  if (error instanceof StokHabisError) {
    console.log("Tawarkan menu lain, stok", error.produk, "habis");
  } else if (error instanceof BayarKurangError) {
    console.log("Minta tambahan Rp" + error.kurang);
  } else {
    throw error; // error tak dikenal, lempar lagi
  }
}

Perhatikan pola throw error di akhir: error yang tidak dikenali jangan ditelan diam-diam, lempar kembali supaya tidak menyembunyikan bug.

Jebakan umum

  1. Lupa super(pesan). Constructor class turunan wajib memanggil super() sebelum memakai this, kalau tidak akan error ReferenceError.
  2. Tidak mengatur name. Tanpa itu, semua custom error tampil sebagai "Error" di console dan susah dibedakan saat debugging.
  3. Terlalu banyak class error. Buat hanya untuk kategori yang penanganannya benar-benar berbeda. Lima jenis error yang semuanya ditangani dengan cara sama lebih baik digabung jadi satu.
  4. Menelan error dengan catch kosong. catch (e) {} tanpa isi menyembunyikan masalah. Minimal catat ke console atau lempar ulang.
Live Playground
export default function App(): JSX.Element {
  return <h1>Hello world</h1>
}

Edit kode di kiri, preview kanan ter-update otomatis.

Tantangan

Error Login yang Spesifik

Di dunia nyata, pesan error login yang generik membuat frustrasi: user tidak tahu apakah salah password, akun belum terdaftar, atau server sedang mati. Tantangan ini melatihmu merancang error yang informatif. Buat class AuthError extends Error dengan properti tambahan kode (misalnya "USER_TIDAK_ADA" atau "PASSWORD_SALAH"). Lalu buat fungsi login(username, password) yang melempar AuthError dengan kode yang tepat: user "budi" dengan password "1234" adalah satu-satunya yang valid.

<!doctype html>
<html>
<head>
<meta charset="utf-8" />

</head>
<body>
<h1>Halo JS</h1>
<p>Buka console preview untuk melihat output.</p>
<script src="index.js"></script>
</body>
</html>