exceptionerrortry-catchMahir5 mnt baca

Exception Handling

Menangani error dengan elegan: try-catch, on, finally, dan throw custom exception.

Program yang tidak gampang mati

Error itu pasti terjadi: file tidak ada, internet putus, user memasukkan teks di kolom angka. Exception handling memastikan program menangani error dengan anggun, bukan crash dan menutup paksa.

dart
void main() {
  try {
    int angka = int.parse('bukan angka'); // melempar FormatException
    print(angka);
  } catch (e) {
    print('Terjadi error: $e');
  }
  print('Program tetap jalan');
}

Blok try berisi kode berisiko, catch menangkap errornya. Program lanjut ke baris setelah catch, tidak mati.

on: tangkap tipe spesifik

Kadang error berbeda butuh penanganan berbeda:

dart
void main() {
  try {
    int angka = int.parse('abc');
    var list = [1, 2, 3];
    print(list[10]);
  } on FormatException catch (e) {
    print('Format salah: $e');
  } on RangeError catch (e) {
    print('Index keluar batas: $e');
  } catch (e) {
    print('Error lain: $e');
  }
}

on FormatException hanya menangkap error tipe itu. Urutan penting: yang spesifik dulu, catch umum paling akhir sebagai jaring pengaman.

finally: selalu dijalankan

dart
void main() {
  try {
    print('Buka koneksi...');
    throw Exception('Koneksi putus!');
  } catch (e) {
    print('Tangkap: $e');
  } finally {
    print('Tutup koneksi.'); // selalu jalan, error atau tidak
  }
}

Blok finally cocok untuk bersih-bersih: tutup file, tutup koneksi database, sembunyikan loading spinner.

throw: melempar error sendiri

Fungsi juga boleh "protes" kalau inputnya tidak masuk akal:

dart
double bagi(double a, double b) {
  if (b == 0) {
    throw Exception('Pembagi tidak boleh nol!');
  }
  return a / b;
}

void main() {
  try {
    print(bagi(10, 0));
  } catch (e) {
    print('Gagal: $e');
  }
}

Custom exception: error yang bermakna

Untuk aplikasi serius, bikin class exception sendiri supaya pesannya jelas:

dart
class SaldoKurang implements Exception {
  final String pesan;
  SaldoKurang(this.pesan);

  @override
  String toString() => 'SaldoKurang: $pesan';
}

void tarik(double saldo, double jumlah) {
  if (jumlah > saldo) {
    throw SaldoKurang('Butuh Rp$jumlah tapi saldo cuma Rp$saldo');
  }
  print('Tarik Rp$jumlah berhasil');
}

void main() {
  try {
    tarik(50000, 100000);
  } on SaldoKurang catch (e) {
    print(e); // SaldoKurang: Butuh Rp100000.0 tapi saldo cuma Rp50000.0
  }
}

Catatan teknis: Jangan pakai try-catch untuk logika normal program. Exception itu untuk kondisi luar biasa, bukan alur biasa. Contoh salah: pakai try-catch untuk cek apakah key ada di map (pakai containsKey saja). Exception itu mahal dan membuat alur kode sulit diikuti. Aturannya: kalau bisa dicek dengan if, pakai if.

Exception dan async

Error di dalam Future ditangkap dengan try-catch di sekitar await:

dart
Future<String> ambilData() async {
  await Future.delayed(Duration(seconds: 1));
  throw Exception('Server error 500');
}

void main() async {
  try {
    await ambilData();
  } catch (e) {
    print('Gagal ambil data: $e');
  }
}

Tanpa try-catch, error async jadi unhandled dan bisa crash aplikasi. Di Flutter, selalu bungkus pemanggilan API dengan try-catch dan tampilkan pesan ramah ke user.