Crash total adalah reaksi yang terlalu keras untuk kesalahan kecil. Ketika pengguna mengetik “dua puluh” pada kolom umur, program seharusnya bisa meminta input ulang, bukan mati dengan traceback. Perangkat Python untuk itu adalah pernyataan try dan except. Pada Chapter ini kita akan membedah cara kerja penangkapan exception, mengapa klausa except harus ditulis spesifik, dan bagaimana membaca isi exception yang tertangkap.
Menangkap Exception dengan try dan except #
Pernyataan try membungkus kode yang berisiko gagal. Mekanismenya: interpreter Python menjalankan blok try baris demi baris. Begitu sebuah exception muncul, interpreter Python meninggalkan sisa blok try saat itu juga, lalu mencari klausa except yang cocok dengan class exception tersebut. Jika cocok, blok handler dijalankan dan program lanjut hidup; jika tidak ada, exception diteruskan keluar seperti perilaku default yang kita lihat pada Chapter Memahami Exceptions.
umur_text = "dua puluh"
try:
umur = int(umur_text)
print("Konversi berhasil:", umur)
except ValueError:
print("Input bukan angka yang valid")Output yang Dihasilkan:
Input bukan angka yang validMari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 3 (
try:): interpreter Python mulai menjalankan bloktrydengan pengawasan. - Baris 4 (
umur = int(umur_text)): functionint()gagal mengonversi string"dua puluh"dan membangkitkanValueError. Baris 5 tidak pernah dieksekusi. - Baris 6 (
except ValueError:): interpreter Python mencocokkan class exception dengan klausa ini — cocok, jadi blok handler dijalankan. - Baris 7 (
print(...)): pesan cadangan dicetak, lalu eksekusi normal berlanjut ke kode setelah pernyataantry.
Perhatikan bahwa print() pada baris 5 tidak pernah berjalan. Saat exception muncul di tengah blok try, seluruh sisa baris blok tersebut dilewati.
Tangani Exception yang Spesifik #
Klausa except yang menyebut nama class secara eksplisit menjelaskan kegagalan apa yang dipersiapkan program. Contoh berikut menangkap IndexError saat membaca list:
peserta = ["Budi", "Siti"]
try:
print("Peserta ketiga:", peserta[2])
except IndexError:
print("Nomor peserta tidak ditemukan")Output yang Dihasilkan:
Nomor peserta tidak ditemukanHandler spesifik memberi dua manfaat. Pertama, niat kode terbaca jelas: blok tersebut hanya bereaksi terhadap kehabisan index. Kedua, bug lain tetap bocor keluar — misalnya TypeError akibat salah tipe — sehingga tetap terlihat saat pengembangan, bukan tertelan diam-diam.
Bahaya bare except #
Klausa except: tanpa nama class, disebut bare except, menangkap semua exception tanpa terkecuali. Perhatikan kasus berikut:
def tampilkan_diskon(persentase):
print(f"Diskon hari ini: {persentase}%")
try:
tampil_diskon(20)
except:
print("Terjadi kesalahan")Output yang Dihasilkan:
Terjadi kesalahanKode di atas tidak jalan sebagaimana mestinya: nama function tertulis tampil_diskon, padahal definisinya tampilkan_diskon. Kesalahan ketik itu membangkitkan NameError, dan bare except menelan error tersebut seolah-olah itu bagian dari alur normal. Programmer jadi tidak menyadari ada bug.
Ringkasan tiga pola klausa except:
| Pola | Cakupan | Kapan pantas |
|---|---|---|
except: | seluruh BaseException, termasuk Ctrl+C dan SystemExit | hampir tidak pernah |
except Exception: | hampir seluruh exception runtime | jaring pengaman di lapisan teratas |
except ValueError: | hanya ValueError (dan sub-class-nya) | pilihan utama sehari-hari |
Mengakses Exception dengan as #
Exception yang tertangkap bisa diikat ke variabel dengan klausa except ... as e. Variabel tersebut adalah object exception utuh, sehingga kita bisa membaca class-nya dan isi pesannya:
umur_text = "2O"
try:
umur = int(umur_text)
except ValueError as e:
print("Tipe exception :", type(e).__name__)
print("Isi pesan :", e)
print("Atribut args :", e.args)Output yang Dihasilkan:
Tipe exception : ValueError
Isi pesan : invalid literal for int() with base 10: '2O'
Atribut args : ("invalid literal for int() with base 10: '2O'",)Mari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 4 (
umur = int(umur_text)): string"2O"mengandung huruf O, bukan angka nol, sehingga konversi gagal danValueErrordibangkitkan. - Baris 5 (
except ValueError as e:): interpreter Python mencocokkan class, lalu mengikat object exception ke variabele. - Baris 6–8 (
print(...)):type(e).__name__memberi nama class,eotomatis dikonversistr(e)menjadi pesan, dane.argsmenampung argumen asli pembentuk exception.
Variabel e hanya hidup di dalam blok handler. Setelah blok except selesai, nama e dihapus dari scope — kita sudah membahas mekanisme scope pada Chapter Scope dan Namespace.
Satu blok try sering kali perlu bereaksi terhadap beberapa jenis kegagalan sekaligus. Cara mengaturnya menjadi bahasan Chapter Menangani Beberapa Exceptions.