Exception & ErrorHandling — Yang Bertanggung Jawab

Perbandingan Exception & ErrorHandling Antara Python Dan Golang

Sebelum membaca lebih lanjut tulisan ini, tolong jangan berpikiran kalau tulisan ini adalah tentang flame war antara Python & Golang, tapi justru akan membahas tentang manajemen error / exception handling secara general, Python & Golang hanya dipakai sebagai pembanding dan sebagai contoh source code.

Dan sebagai catatan, definisi “error” di Golang adalah sebuah value dan memiliki interface nya sendiri, dan tidak ada istilah `try catch` atau `exception` di Golang.


Di dalam software development, kita tentunya 100% pasti akan berhadapan dengan berbagai macam kemungkinan error. Baik itu bahasa interpreter atau compiled, semuanya pasti akan mengalami runtime error, kalau ada sebuah error atau exception yang belum kita handle. Ketika runtime error ini terjadi dan tidak ada mekanisme handling nya, user yang menggunakan aplikasi kita, biasanya akan “disuguhi” pemandangan yang menurut saya “kurang nyaman” atau bahkan mungkin OS bisa crash.

Ok kita langsung saja ke contoh kasusnya. Story :

Ada sebuah library yang tugasnya adalah untuk melakukan koneksi HTTP untuk mengakses sebuah REST API.

Contoh lib di python :

Contoh lib di golang :

Library yang saya buat ini cukup sederhana & simpel penggunaannya pun gampang.

Di python

pyhttp = ConsumeApi()
response = pythttp.get()

Di golang

gohttp := consumeapi.New()
resp, err := gohttp.Get()

Kalau semuanya berjalan normal, ok, ini adalah impian semua programmer (software berjalan normal), tapi kalau ada exception ketrigger atau ada error ?


Python

Untuk sementara saya akan menjelaskan exception handling di python dulu.

try:

pyhttp = ConsumeApi()
response = pyhttp.get()
catch Exception:
    //yes we catch the error!

Untuk sementara kelihatannya semua baik-baik saja, aman, tentram, bahagia bin sentosa. Tapi sebenarnya manajemen handling exception yang seperti ini justru yang berbahaya. Karena kita sebenarnya tidak tahu apa yang sebenarnya terjadi, kita hanya tahu, kalau ada exception ke trigger, dan itu pun top class exception.

Seperti yang saya tulis di lib python di atas, kalau lib sederhana python di tulisan ini menggunakan library third party yaitu requests (rata-rata programmer python pasti sudah familiar dengan lib ini). Dan sekarang saya coba untuk memberikan daftar exception apa saja yang akan ditrigger oleh lib ini :

  1. ConnectionError. Exception ini akan ditrigger jika ada masalah di jaringan (network).
  2. HTTPError. Exception ini akan ditrigger jika ada masalah di HTTP response code.
  3. Timeout. Request timeout
  4. TooManyRedirects. Exception ini akan ditrigger jika url endpoint yang kita akses melakukan proses redirect yang cukup banyak.

Ada empat kemungkinan error yang bisa terjadi. Yang tentunya mekanisme handling exception untuk keempat exception di atas seharusnya berbeda. Yaitu :

try:

pyhttp = ConsumeApi()
response = pyhttp.get()
catch requests.exceptions.ConnectionError:
    # send message to user about connection error
# or do something like retry
catch requests.exception.HTTPError:

# send message to user about http error
catch requests.exceptions.Timeout:
    # do retry
catch requests.exceptions.TooManyRedirects:
    # requested endpoint is broken
catch Exception:
    # no more error can run from us!

Bandingkan dengan kode `try catch` kita yang pertama, cukup jauh kan ? Apa kelemahan dari mekanisme seperti ini ?

  1. Capek. Otomatis kalau memang ada banyak exception / error, kita akan capek untuk nge-catch satu per satu exceptionnya. Strategi nya mungkin kita bisa membuat custom exception miliki kita sendiri yang nantinya extend dari `requests.exceptions.RequestException` dimana kita bisa menglist kemungkinan error apa saja hanya dari satu custom exception milik kita sendiri.

Dan harap diingat, kalau saya tetap memakai top class Exception. Penggunaan top class Exception itu tetap tidak ada masalah, hanya saja digunakan di akhir dari sebuah proses catch, tetapi prioritas catch error tetap lebih baik per spesifik exception.


Golang

Sekali lagi saya ingatkan kalau tidak ada mekanisme try catch dan exception di golang. Lalu bagaimana error handling di golang ?

Golang memaksa seluruh programmer yang menggunakan dirinya, untuk melakukan pemeriksaan error satu persatu

Inilah kenapa kita akan sering menemui proses seperti ini di golang :

if err != nil {
  fmt.Println("woops, some error happened")
}

Seperti melakukan pemeriksaan sebuah variable kan ? Ini karena error di golang adalah sebuah value.

Awal mula saya belajar golang (dan sampai sekarang masih belajar juga), saya beranggapan hal ini adalah aneh, tidak elegan dan melelahkan. Tapi setelah saya coba untuk membiasakan diri dan belajar tentang konsep & sejarah Golang, akhirnya saya paham kenapa di Golang menggunakan mekanisme seperti ini, dan jawabannya sangat sederhana :

Programmerlah yang seharusnya bertanggung jawab penuh untuk masalah error handling

Dan satu lagi yang perlu diingat adalah, proses handling error itu memang sudah kodratnya melelahkan.


Selamat berburu error!