Episode ini membedah penanganan error di Ruby: begin, rescue, ensure, dan raise, kelas exception StandardError dan ArgumentError, custom exception, debugging dengan binding.irb dan gem debug, membaca backtrace, serta menjalankan kode dengan ruby -w.

Program yang tidak pernah error adalah mitos. Yang membedakan developer andal adalah cara menghadapi error: menangkapnya dengan benar, memahami pesan dan backtrace, lalu memperbaikinya dengan alat yang tepat. Ruby menyediakan sistem exception yang matang dan tooling debugging yang sangat nyaman.
Episode 7 ini membedah tiga keterampilan: exception handling dengan begin, rescue, ensure, dan raise, debugging interaktif dengan binding.irb dan gem debug, serta penggunaan flag -w untuk menangkap warning dan deprecation lebih awal. Ketiga keterampilan ini akan menyelamatkan kalian berulang kali di sisa series.
Blok begin...rescue...end adalah cara utama menangkap exception di Ruby. rescue menangkap exception, ensure selalu dieksekusi baik terjadi error maupun tidak, dan else hanya berjalan bila tidak ada error:
begin
hasil = 10 / 0
rescue ZeroDivisionError => e
puts "Terjadi error: #{e.message}"
ensure
puts "Blok ensure selalu dijalankan"
endrescue ZeroDivisionError => e menangkap exception pembagian nol dan mengikat objek exception ke variabel e. Method e.message menampilkan pesan deskriptif. Blok ensure berguna untuk menutup koneksi database atau file, sehingga pembersihan resource selalu terjadi.
Exception tidak selalu datang dari kesalahan runtime; kalian bisa melemparkannya sendiri dengan raise. Semua exception adalah objek yang mewarisi kelas Exception, dan penanganan biasanya difokuskan pada StandardError beserta turunannya seperti ArgumentError, RuntimeError, dan TypeError:
class UmurTidakValid < StandardError
end
def cek_umur(umur)
raise UmurTidakValid, "Umur harus positif" if umur < 0
umur
end
begin
cek_umur(-1)
rescue UmurTidakValid => e
puts "Tertangkap: #{e.message}"
endclass UmurTidakValid < StandardError mendefinisikan custom exception yang turun dari StandardError, sehingga otomatis bisa ditangkap rescue. Pemanggilan cek_umur(-1) melempar exception tersebut, dan rescue UmurTidakValid menangkapnya. Memakai exception yang spesifik memudahkan penanganan yang berbeda-beda.
Hindari rescue Exception tanpa filter karena bisa menelan error fatal seperti NoMemoryError dan SystemExit. Tangkap kelas exception yang paling spesifik yang kalian harapkan. Jika ada beberapa kemungkinan, tulis beberapa baris rescue berurutan mulai dari yang paling spesifik.
Cara tercepat memeriksa state program adalah binding.irb — menghentikan eksekusi dan membuka sesi IRB di titik tersebut, tempat semua variabel lokal bisa diinspeksi:
def hitung(a, b)
hasil = a + b
binding.irb
hasil * 2
end
puts hitung(3, 4)Saat eksekusi mencapai binding.irb, program berhenti dan kalian bisa mengetik hasil untuk melihat nilainya (yaitu 7), memanggil method, bahkan mengubah variabel, lalu ketik exit untuk melanjutkan. Ini adalah debugging loop paling cepat yang dimiliki Ruby.
Untuk kontrol lebih baik, gem debug (modul ruby/debug) menyediakan binding.break dengan debugger interaktif penuh: step, next, continue, dan inspeksi stack. Pasang dan jalankan seperti ini:
gem install debug
ruby -r debug script.rbCommand ruby -r debug script.rb memuat modul debug sebelum menjalankan script. Ketika eksekusi menyentuh binding.break, debugger terbuka dengan perintah seperti step, next, continue, dan backtrace. Mode ini jauh lebih kuat daripada binding.irb untuk mencari bug di kode yang kompleks.
Saat exception tidak tertangkap, Ruby mencetak backtrace — urutan pemanggilan dari titik error naik ke pemanggil terluar:
script.rb:3:in `hitung': divided by 0 (ZeroDivisionError)
from script.rb:7:in `<main>'Baris pertama menunjukkan lokasi error sebenarnya (file script.rb baris 3, method hitung), dan baris berikutnya menunjukkan siapa pemanggilnya. Baca dari atas ke bawah: baris paling atas adalah akar masalah, sisanya adalah jejak pemanggilan.
Ruby menyembunyikan banyak peringatan yang berguna demi output yang bersih. Flag -w mengaktifkan verbose warning, menampilkan deprecation dan pola mencurigakan yang belum fatal:
ruby -w script.rbCommand ruby -w script.rb menampilkan warning seperti penggunaan method yang sudah usang atau penulisan variabel yang mencurigakan. Kebiasaan ini sangat penting menjelang upgrade versi — di episode 21 kalian akan memakai ruby -w untuk menemukan deprecation saat migrasi Ruby 3.4 ke 4.0.
Warning di Ruby tidak menghentikan eksekusi, tetapi menandakan perilaku yang akan berubah atau berpotensi bug. Saat melihat warning, jangan ditunda — baca dan pahami penyebabnya. Di Ruby 4.0, frozen string literal sudah menjadi default, sehingga banyak warning di kode lama terkait mutasi string yang akan berubah perilakunya.
Warning
Selalu jalankan test suite dengan ruby -w selama pengembangan. Warning yang muncul di development hampir selalu menjadi error atau perilaku berbeda di produksi setelah upgrade versi Ruby.
Episode 7 membekali kalian dengan pertahanan terhadap error: exception handling dengan begin, rescue, ensure, dan raise, custom exception yang spesifik, debugging interaktif dengan binding.irb dan gem debug, membaca backtrace, serta penggunaan ruby -w untuk menangkap warning sejak dini.
Inti yang harus dibawa pulang:
begin, rescue, ensure, dan else mengontrol alur saat exception terjadi.raise melempar exception; custom exception turun dari StandardError.rescue Exception polos.binding.irb membuka sesi IRB di titik breakpoint.debug menyediakan debugger penuh dengan binding.break.ruby -w mengaktifkan warning dan deprecation untuk menangkap masalah lebih awal.Di episode 8 selanjutnya kita akan membahas string, symbol, dan regular expression — pengelolaan encoding string, perbedaan mutable dan frozen string literal, method umum seperti split, gsub, tr, dan upcase, serta regexp dengan capture group, method match, scan, dan flag i, m, x. Ini keterampilan pengolahan teks yang wajib dimiliki developer backend.