Learn
← Previous Next →

Hari 20: Exception Handling — try, except, finally

60 min Last updated 26 Mar 2026

Mengapa Exception Handling?

Program yang baik tidak hanya berjalan saat input sempurna — ia harus menangani kondisi tak terduga dengan graceful.

try / except Dasar

# Tanpa handling — program crash
# print(10 / 0)  # ZeroDivisionError

# Dengan handling
try:
    hasil = 10 / 0
except ZeroDivisionError:
    print("Error: tidak bisa bagi nol")

# Tangkap berbagai exception
try:
    x = int(input("Masukkan angka: "))
    print(10 / x)
except ValueError:
    print("Input bukan angka!")
except ZeroDivisionError:
    print("Tidak bisa bagi nol!")
except Exception as e:
    print(f"Error tak terduga: {e}")

else & finally

try:
    f = open("data.txt", "r")
    isi = f.read()
except FileNotFoundError:
    print("File tidak ditemukan!")
else:
    # Dijalankan HANYA jika tidak ada exception
    print(f"Berhasil baca {len(isi)} karakter")
finally:
    # Selalu dijalankan, exception atau tidak
    print("Selesai memproses file")
    # f.close()  # pastikan file ditutup

Exception Hierarchy

# BaseException
#   └── Exception
#         ├── ValueError     — nilai tidak valid
#         ├── TypeError      — tipe data salah
#         ├── KeyError       — key dict tidak ada
#         ├── IndexError     — indeks di luar range
#         ├── AttributeError — atribut tidak ada
#         ├── ZeroDivisionError
#         ├── FileNotFoundError
#         └── ...

# Tangkap banyak exception sekaligus
try:
    data = [1, 2, 3]
    print(data[10])
except (IndexError, KeyError) as e:
    print(f"Akses data gagal: {e}")

Custom Exception

class SaldoTidakCukup(Exception):
    def __init__(self, saldo, jumlah):
        self.saldo  = saldo
        self.jumlah = jumlah
        super().__init__(f"Saldo Rp {saldo:,} tidak cukup untuk tarik Rp {jumlah:,}")

class PINSalah(Exception):
    pass

def tarik_tunai(saldo, pin_input, pin_benar, jumlah):
    if pin_input != pin_benar:
        raise PINSalah("PIN yang dimasukkan salah!")
    if jumlah > saldo:
        raise SaldoTidakCukup(saldo, jumlah)
    return saldo - jumlah

try:
    sisa = tarik_tunai(500_000, "1234", "1234", 600_000)
except PINSalah as e:
    print(f"Gagal: {e}")
except SaldoTidakCukup as e:
    print(f"Gagal: {e}")

raise & re-raise

def validasi_umur(umur):
    if not isinstance(umur, int):
        raise TypeError(f"Umur harus int, bukan {type(umur).__name__}")
    if umur < 0 or umur > 150:
        raise ValueError(f"Umur tidak valid: {umur}")
    return umur

try:
    validasi_umur("dua puluh")
except TypeError as e:
    print(f"TypeError: {e}")
    raise  # re-raise exception yang sama

Assignment

Buat class KalkuatorAman yang membungkus semua operasi dengan exception handling. Setiap operasi harus: menangani ZeroDivisionError, TypeError (input bukan angka), dan ValueError (sqrt dari negatif).

Expected output:

5.0
Error: pembagi tidak boleh nol
Error: input harus berupa angka
4.0
Error: Tidak bisa akar kuadrat dari -4
1024
PY main.py
Solution
Output