Belajar Python Error Handling Try Except

| | Python
Belajar Python Error Handling Try Except

error (exception) itu hal yang wajar dalam pemrograman, bukan tanda kalian gagal. yang membedakan programmer yang baik adalah cara menangani error tersebut, dan python nyediain try-except buat nanganin error dengan elegan. konsep ini bakal sering banget kalian pakai waktu mulai bikin fungsi sendiri atau nyusun kode ke module.

saya dulu sering nulis kode tanpa try-except sama sekali, sampai aplikasi yang saya buat tiba-tiba berhenti total di depan klien gara-gara satu file yang tidak ditemukan. sejak kejadian itu, menangani error dengan benar jadi bagian wajib dari setiap kode yang saya tulis, bukan sekadar pelengkap.

1. Kenapa Perlu Error Handling?

di python, semua error itu object, dan mereka punya silsilah (hierarchy):

BaseException
├── SystemExit          # dari sys.exit()
├── KeyboardInterrupt   # user tekan Ctrl+C
└── Exception           # error aplikasi biasa, mulai dari sini
    ├── ValueError
    ├── TypeError
    ├── ZeroDivisionError
    ├── FileNotFoundError
    └── ... dan banyak lagi

tanpa try-except, error sekecil apa pun langsung menghentikan program. dengan try-except, kalian bisa menangkap errornya, kasih pesan yang jelas ke user, dan biarkan program tetap jalan.

2. Syntax Dasar

bentuk paling sederhananya begini:

try:
    # Kode yang mungkin error
    hasil = 10 / 0
except ZeroDivisionError:
    # Kode jika error terjadi
    print("Tidak bisa dibagi nol!")

perhatikan except di atas menangkap jenis error yang spesifik, yaitu ZeroDivisionError. itu cara yang benar. hindari except: polos karena dia menangkap semua error, termasuk KeyboardInterrupt waktu user mau menghentikan program pakai Ctrl+C, yang seharusnya dibiarkan jalan.

3. Menangani Error Spesifik

satu blok try bisa punya beberapa except, satu buat tiap jenis error:

try:
    angka = int(input("Masukkan angka: "))
    hasil = 10 / angka
    print(f"Hasil: {hasil}")
except ValueError:
    print("Input harus angka!")
except ZeroDivisionError:
    print("Tidak bisa dibagi nol!")
except Exception as e:
    print(f"Error tidak terduga: {e}")

urutan except itu penting, python ngecek dari atas ke bawah. karena Exception itu induk dari hampir semua error, dia harus ditaruh paling bawah, kalau tidak, except yang lebih spesifik tidak akan pernah jalan.

kalau beberapa jenis error butuh penanganan yang sama, gabungin pakai tuple:

try:
    nilai = int("abc")
except (ValueError, TypeError) as e:
    print(f"Salah tipe atau nilai: {e}")

4. Else dan Finally

else jalan kalau blok try sukses, dan finally selalu jalan apa pun yang terjadi, bahkan kalau ada return atau raise di dalam try:

file = None
try:
    file = open("data.txt", "r", encoding="utf-8")
    isi = file.read()
except FileNotFoundError:
    print("File tidak ditemukan")
else:
    print(f"Isi file: {isi}")  # jalan kalau tidak ada error, jangan taruh di dalam try
finally:
    if file:
        file.close()  # selalu jalan, bahkan kalau except raise lagi
        print("File ditutup")

dua detail penting di contoh ini. pertama, file diisi None di awal, supaya finally aman kalau open() gagal, tanpa itu file tidak terdefinisi dan malah muncul error baru. kedua, else berguna buat nandain kode yang memang cuma boleh jalan kalau tidak ada error, jadi tidak semua harus ditaruh di dalam try. kalau kalian taruh kode sukses di dalam try, error dari kode itu ikut ketangkap except yang tidak seharusnya.

catatan: buat file, cara paling aman sebenarnya pakai with open(), yang otomatis nutup file meski error. with sendiri pakai try/finally di dalam. contoh di atas pakai try-finally buat nunjukin konsepnya, tapi di project beneran, with hampir selalu lebih baik.

5. Raise, Lempar Error Sendiri

kalian juga bisa melempar error secara sengaja buat ngejaga validitas data:

def set_umur(umur):
    if umur < 0:
        raise ValueError("Umur tidak boleh negatif!")
    if umur > 150:
        raise ValueError("Umur tidak valid!")
    print(f"Umur: {umur}")

try:
    set_umur(-5)
except ValueError as e:
    print(e)  # Umur tidak boleh negatif!

raise ini kunci dari pola “fail fast”, gagal cepat dan jelas lebih baik daripada program jalan tapi diam-diam salah.

kalau mau melempar ulang error yang baru saja ditangkap, tulis raise tanpa argumen di dalam except, ini jaga traceback asli:

try:
    buka_file_rahasia()
except PermissionError:
    logging.error("User tidak punya akses")
    raise  # lempar ulang error yang sama ke pemanggil, traceback tetap utuh

sedangkan kalau kalian mau translate error ke tipe sendiri tapi tetap simpan penyebabnya, pakai raise ... from:

try:
    int("abc")
except ValueError as e:
    raise RuntimeError("Gagal parse data") from e
    # traceback akan tulis: "The above exception was the direct cause"

kalau rantai error bikin bising dan penyebabnya sudah jelas, pakai from None biar traceback lebih ringkas:

try:
    data["nama"]
except KeyError:
    raise AttributeError("nama tidak ada") from None

6. Custom Exception

buat error dengan nama yang jelas supaya kode kalian enak dibaca:

class SaldoTidakCukupError(Exception):
    def __init__(self, saldo, dibutuhkan):
        self.saldo = saldo
        self.dibutuhkan = dibutuhkan
        super().__init__(f"Saldo Rp{saldo} tidak cukup. Dibutuhkan Rp{dibutuhkan}")

def tarik_tunai(saldo, jumlah):
    if jumlah > saldo:
        raise SaldoTidakCukupError(saldo, jumlah)
    return saldo - jumlah

try:
    tarik_tunai(50000, 100000)
except SaldoTidakCukupError as e:
    print(e)

custom exception itu cuma class biasa yang mewarisi Exception. bedanya, error aplikasi kalian sekarang punya nama sendiri, jadi waktu muncul di log, langsung kelihatan masalahnya di domain apa, bukan tebak-tebakan dari ValueError generik.

7. Logging Error dengan Traceback

buat production, jangan cuma print, pakai logging supaya errornya terekam lengkap dengan jejak barisnya:

import logging
logging.basicConfig(level=logging.ERROR)

try:
    hasil = 10 / 0
except Exception as e:
    logging.error(f"Error: {e}", exc_info=True)
    # shortcut yang sama: logging.exception(f"Error: {e}") otomatis exc_info=True

parameter exc_info=True bikin logging nyimpen traceback lengkap, jadi kalian tahu persis baris mana yang error. ini perbedaan besar sama print yang cuma nampilin pesan tanpa konteks.

satu lagi aturan emas: jangan diamkan error. blok except yang isinya cuma pass itu nyembunyiin bug, dan bug yang disembunyiin bakal meledak di tempat lain yang susah dilacak. minimal log, atau lempar ulang. PEP 760 bahkan sempat usulin untuk melarang except: polos sama sekali karena terlalu berbahaya, jadi biasakan except Exception atau tipe spesifik.

8. Studi Kasus: Baca Data Pengguna dari File

gabungin semua konsep di satu program yang realistis:

import logging
logging.basicConfig(level=logging.ERROR)

def baca_pengguna(nama_file):
    try:
        with open(nama_file, "r") as f:
            data = []
            for baris in f:
                nama, umur = baris.strip().split(",")
                if int(umur) < 0:
                    raise ValueError(f"Umur negatif untuk {nama}")
                data.append((nama, int(umur)))
    except FileNotFoundError:
        print(f"File {nama_file} tidak ditemukan")
        return []
    except ValueError as e:
        logging.error(f"Format data salah: {e}", exc_info=True)
        return []
    else:
        print(f"Berhasil baca {len(data)} pengguna")
        return data

pengguna = baca_pengguna("users.csv")

program ini nanganin file yang hilang, format data yang salah, dan data yang tidak masuk akal, tiga jenis error yang paling sering muncul di dunia nyata.

Kesimpulan

  • try itu blok kode yang mungkin error, except buat nanganinnya
  • tangkap error yang spesifik, hindari except: polos, dan taruh except Exception paling bawah
  • else jalan kalau tidak ada error, finally selalu jalan buat cleanup
  • raise buat lempar error sendiri, raise polos buat lempar ulang
  • custom exception bikin error aplikasi punya nama yang jelas
  • pakai logging dengan exc_info=True, jangan pernah diamkan error dengan pass

Baca Juga Mengenai :


Pertanyaan yang Sering Diajukan

Apa itu try except di Python?

try except itu struktur buat menangkap error (exception) supaya program tidak langsung berhenti. kode yang berisiko ditaruh di blok try, dan penanganan errornya di blok except.

Apa bedanya except polos dan except Exception?

except polos menangkap semua jenis error termasuk KeyboardInterrupt dan SystemExit yang sebaiknya dibiarkan. except Exception lebih aman karena cuma menangkap error aplikasi biasa. hindari except polos.

Kapan pakai else dan finally?

else jalan kalau blok try sukses tanpa error, cocok buat kode lanjutan yang tidak perlu dilindungi. finally selalu jalan apa pun hasilnya, cocok buat cleanup seperti nutup file atau koneksi database.

Bagaimana cara lempar error sendiri di Python?

pakai raise. contohnya raise ValueError("Umur tidak boleh negatif"). kalau mau lempar ulang error yang sudah ditangkap, tulis raise saja tanpa argumen di dalam blok except.

Apa itu custom exception dan kapan dipakai?

custom exception itu class error buatan sendiri yang mewarisi Exception. dipakai supaya error aplikasi kalian punya nama yang jelas, misal SaldoTidakCukupError, sehingga gampang ditangkap dan dibedakan dari error bawaan python.

Kenapa error tidak boleh didiamkan dengan pass?

karena bug jadi tidak kelihatan dan susah dilacak. minimal log errornya pakai logging, atau lempar ulang. pass di blok except itu seperti nutup mata di jalan raya.

Bagaimana cara menangkap banyak jenis error sekaligus?

pakai tuple di except, misalnya except (ValueError, TypeError) as e. cocok kalau beberapa jenis error butuh penanganan yang sama.

Sigit Nurhanafi avatar
Full-stack developer & technical writer. Berpengalaman di PHP, Laravel, NodeJS, MySQL, dan Python. Aktif menulis tutorial pemrograman dan maintaining open-source projects di PemburuKode sejak 2021.