1 poin oleh GN⁺ 2025-06-04 | 1 komentar | Bagikan ke WhatsApp
  • Verbosity penanganan error di bahasa Go sudah lama menjadi salah satu keluhan teratas dari pengguna
  • Berbagai usulan perbaikan sintaksis (misalnya check/handle, try, operator ?, dll.) telah dibahas dan diuji, tetapi semuanya ditolak tanpa konsensus komunitas yang memadai
  • Dampak luas perubahan bahasa terhadap kode, alat, dokumentasi, dan lain-lain, serta prinsip Go untuk mempertahankan kesederhanaan khasnya, menjadi pertimbangan utama
  • Karena kejelasan, kemudahan debugging dari cara saat ini dan juga preferensi sebagian pengguna, alasan untuk memaksakan perubahan sintaks dinilai lemah
  • Tidak ada rencana perubahan sintaks penanganan error untuk masa depan yang terlihat, dan semua usulan terkait akan ditutup tanpa penyelidikan tambahan

Mengangkat masalah verbosity penanganan error di Go

  • Salah satu keluhan lama terhadap Go adalah bahwa sintaks penanganan error terlalu bertele-tele
  • Pola seperti if err != nil secara khas muncul berulang kali di dalam kode
  • Semakin banyak pemanggilan API yang dibutuhkan sebuah program, semakin menonjol pola ini, hingga kode penanganan error bisa lebih banyak daripada logika utamanya
  • Dalam survei pengguna tahunan, keluhan ini terus muncul di peringkat atas

Diskusi dengan komunitas dan usulan awal

  • Tim Go terus meneliti usulan perbaikan penanganan error dengan menekankan pentingnya masukan komunitas
  • Dalam diskusi proyek Go 2 pada 2018, Russ Cox secara resmi merangkum inti persoalan penanganan error
    • Muncul rancangan mekanisme check dan handle yang diusulkan Marcel van Lohuizen
    • Termasuk perbandingan dengan bahasa-bahasa serupa dan peninjauan berbagai alternatif
  • Pendekatan ini memang membuat kode lebih ringkas, tetapi tidak diadopsi karena menambah kompleksitas

Usulan try dan setelahnya

  • Pada 2019, diajukan usulan fungsi bawaan try yang jauh lebih sederhana
    • Hanya mengkodekan fungsi check, sementara handle dihilangkan
    • Usulan ini dikritik karena menyembunyikan alur kontrol dan akhirnya dibatalkan di tengah penolakan komunitas
  • Dari pengalaman ini muncul pemahaman tentang risiko usulan yang terlalu matang tanpa umpan balik yang cukup
    • Untuk usulan perubahan besar, penting mengumpulkan pendapat lebih luas sejak tahap desain awal

Upaya tambahan dan beragam usulan

  • Banyak variasi dan pendekatan alternatif untuk penanganan error terus bermunculan dari komunitas
    • Kondisinya dirangkum dalam umbrella issue oleh Ian Lance Taylor, sementara contoh-contoh terus dikumpulkan di Go Wiki, blog, dan tempat lain
  • Pada 2024, muncul usulan menerapkan operator ? yang dipinjam dari Rust
    • Dalam uji kegunaan skala kecil, ada masukan bahwa pendekatan ini terasa intuitif, tetapi tetap tidak mencapai konsensus di tengah beragam pendapat

Kebuntuan diskusi dan kesimpulan

  • Meski ada lebih dari tiga usulan resmi maupun tidak resmi, dan ratusan usulan dari komunitas, semuanya ditolak karena kurangnya kesepahaman/konsensus yang memadai
  • Bahkan kelompok arsitek internal Go sendiri belum sepakat soal arahnya
  • Sampai ada perubahan situasi atau terbentuk kesepahaman khusus, diputuskan untuk menghentikan upaya perubahan sintaks penanganan error itu sendiri

Argumen utama untuk mempertahankan cara saat ini

  • Jika gula sintaksis sudah dimasukkan sejak desain awal bahasa, mungkin tidak akan menimbulkan kontroversi, tetapi sekarang ekosistem sudah terbiasa dengan cara yang dipakai selama 15 tahun
  • Jika sintaks baru diperkenalkan, akan ada kekhawatiran tentang jarak gaya penulisan kode antara pengguna lama dan baru serta runtuhnya konsistensi
  • Ini juga sejalan dengan filosofi desain Go (tidak melakukan hal yang sama dengan banyak cara) dan prinsip yang menekankan kesederhanaan/konsistensi
    • Izin redeklarasi pada deklarasi variabel singkat (:=) juga merupakan perubahan sampingan yang lahir dari penanganan error
  • Sintaks penanganan error yang eksplisit (melalui if) punya kekuatan intuitif untuk membaca kode, melakukan debugging, dan memasang breakpoint
  • Perubahan bahasa juga merupakan beban besar dari sisi cakupan perubahan nyata (kode, dokumentasi, alat, dll.) dan biayanya

Perbaikan alternatif dan arah ke depan

  • Penguatan fitur pustaka standar (misalnya penambahan cmp.Or) dapat mengurangi sebagian kode berulang
  • Dengan code folding, autocomplete, pemanfaatan LLM di IDE dan alat pengembangan, verbosity bisa sampai taraf tertentu diatasi dalam praktik
  • Di kelompok pengguna Go utama (misalnya peserta acara Google Cloud Next), pandangan yang menolak perlunya perubahan bahasa lebih dominan
    • Semakin lama memakai Go, masalah verbosity ini justru makin jarang terasa secara nyata

Argumen yang mendukung perlunya perbaikan sintaks

  • Berdasarkan masukan pengguna, tuntutan untuk memperbaiki sintaks penanganan error masih tetap ada
  • Sintaks penanganan error yang bukan sekadar mengurangi jumlah karakter, tetapi juga meningkatkan kejelasan mungkin dapat membantu meningkatkan kualitas/keamanan kode
  • Diperlukan penelitian yang lebih mendalam terhadap penanganan error yang benar-benar menjalankan peran nyata, bukan sekadar pemeriksaan error sederhana

Kesimpulan akhir dan kebijakan ke depan

  • Dengan mengakui bahwa hingga kini belum ada konsensus maupun perubahan nyata, dinyatakan bahwa untuk masa depan yang terlihat, semua diskusi dan usulan perubahan bahasa sintaktis untuk penanganan error akan dihentikan
  • Proses diskusi dan penelitian yang ada sejauh ini tetap memberi kontribusi tidak langsung pada perbaikan ekosistem dan proses Go
  • Jika di masa depan muncul definisi masalah yang lebih jelas dan konsensus yang lebih kuat, diskusi bisa dibuka kembali
  • Untuk sementara, fokus kebijakan adalah mempertahankan ketangguhan dan kesederhanaan Go, bukan mencoba pendekatan baru

1 komentar

 
GN⁺ 2025-06-04
Komentar Hacker News
  • Jika ingin dengan mudah menyarankan bahwa tim Go seharusnya bisa memilih alternatif lain, saya sangat berharap Anda memeriksa tautan wiki Go2ErrorHandlingFeedback atau pencarian issue GitHub. Hampir semua ide yang diajukan sebenarnya sudah pernah dibahas dengan serius, dan sebagai pengguna yang menghargai pendekatan transparan tim Go, saya sangat menikmati memakai Go setiap hari

    • Dokumen rancangan awal menyebut C++, Rust, dan Swift, tetapi saya sulit menemukan do-notation/for-comprehensions/monadic-let dari bahasa fungsional seperti Haskell/Scala/OCaml yang saya cari. Tim Go tampak seperti master dalam desain bahasa, tetapi pada akhirnya terlihat mentok pada keterbatasan static typing tanpa polimorfisme parametrik seperti Java, sehingga tidak mampu menemukan jawaban untuk masalah error handling. Menurut saya ini berasal dari desain fundamental bahasanya

    • Meski dokumen itu ditulis oleh orang-orang yang cerdas dan berpengalaman, sangat aneh bahwa solusi seperti monad Maybe/Either milik Haskell dan operator bind (do-notation) tidak disebut sama sekali. Padahal itu sama sekali tidak sesulit atau seakademis yang dibayangkan, dan merupakan cara yang sangat elegan serta terbukti untuk meneruskan error dengan aman. Saya tidak tahu kenapa komunitas Go tidak mengadopsikan ini. Saya bersyukur halaman ini ada, tetapi sulit memahami kenapa solusi seterkenal ini dilewatkan

    • Hampir semua bahasa menawarkan berbagai pendekatan yang lebih baik, jadi saya penasaran kenapa hanya di Go masalah ini begitu menonjol. Apakah sekadar tidak ada konsensus, atau memang ada karakteristik khusus Go yang membuat solusi dari bahasa lain tidak cocok?

    • Hal yang sering terlihat dalam kritik terhadap Go adalah kecenderungan orang yang relatif non-ahli berasumsi bahwa para pengembang Go pasti lebih tidak paham bahasa dibanding mereka. Padahal, dalam kebanyakan kasus, pengembang Go justru jauh lebih berpengalaman dan jauh lebih tahu. Kaum non-ahli menganggap bahasa dengan lebih banyak fitur pasti lebih baik, tetapi mengabaikan bahwa yang penting sebenarnya adalah menjaga keseimbangan keseluruhan dengan baik

  • Saya rasa pengguna diuntungkan oleh sikap konservatif Go yang berhati-hati dalam menambahkan fitur bahasa baru. Dalam kasus Swift, perubahan fitur terlalu banyak sehingga sulit dipelajari, dan bahkan di Mac terbaru pun kadang ada pengalaman tidak bisa membangun satu proyek sederhana sekalipun. Karena keyword terus bertambah dan berubah, Swift kurang berkelanjutan untuk dipakai, sedangkan kekuatan Go ada pada konsistensinya

  • Pernah ada situasi pengecualian ketika sebuah fungsi Go mengharapkan fungsi internalnya menghasilkan error, dan jika fungsi internal itu justru tidak menghasilkan error, fungsi luarnya malah harus dianggap gagal. Dalam struktur yang tidak umum seperti itu saya harus bercabang dengan if err == nil, tetapi karena kebiasaan saya menulis if err != nil, saya sempat salah menulisnya dan butuh waktu lama menemukan kesalahannya karena terlalu terbiasa dengan pola yang biasa dipakai. Saya jadi berpikir, andaikan ada dukungan di level bahasa untuk membedakan secara sintaksis antara if err != nil yang sering dipakai dan if err == nil yang jarang dipakai, mungkin kesalahan seperti ini bisa dikurangi

    • Setiap kali saya menulis if err == nil, saya menambahkan komentar // inverted untuk menegaskan polanya. Akan bagus kalau bahasa bisa menanganinya secara otomatis, tetapi untuk saat ini cara seperti ini setidaknya bisa membuat perbedaannya lebih jelas
    • Sebenarnya ini justru argumen menentang perubahan sintaks. Pola if err == nil { return ... } yang sering dipakai malah bisa terlihat lebih canggung di dalam kode. Ada pendapat bahwa cara penanganan error Go saat ini jelas dan mudah dibaca, sehingga banyak orang menyukainya
    • Kebingungan yang sama bisa muncul juga pada pola seperti if fruit != "Apple", jadi secara esensial ini bukan cuma masalah error handling melainkan masalah percabangan kondisi secara umum. Error pada akhirnya juga diperlakukan seperti nilai status lain
    • Ada kemungkinan pencegahan kesalahan di level editor, misalnya dengan membuat IDE atau pengaturan font merender if err != nil seperti simbol khusus agar menyatu secara alami di latar belakang (kurang menonjol), lalu hanya if err == nil yang berbeda dibuat lebih menonjol
    • Ada juga usulan untuk meningkatkan keterbacaan dengan cara editor menampilkan pola seperti if err … { dalam bentuk yang diringkas
  • Saya menyukai pendekatan penanganan error Go yang eksplisit. Saya cukup memahaminya secara sederhana: fungsi selalu berhasil (minimal error) atau bisa gagal. Fungsi yang berpotensi gagal harus ditangani dulu sebelum bisa lanjut ke tahap berikutnya. Banyak bahasa melempar error lewat exception yang naik melalui stack sampai tertangkap, sehingga sering kali hanya memberi tahu di mana error terjadi tanpa banyak petunjuk yang benar-benar berguna. Di Go, kita bisa dengan jelas memilih opsi berikut: 1) mengabaikan error 2) langsung return saat error terjadi 3) me-wrap error untuk menambahkan informasi berguna 4) menafsirkan error tertentu lalu bercabang menanganinya (misalnya mengubahnya menjadi 404). Di Go2 saya ingin mencoba menambahkan tipe Result<Value, Failure> atau tipe error yang lebih spesifik dan dapat dienumerasi. Menurut saya lebih tepat memperkenalkannya di Go 2 demi kompatibilitas dengan Go 1

    • Berdasarkan pengalaman saya, kebijakan penanganan error memang harus diputuskan oleh pemanggil, dan menanganinya di stack level bawah bukan pendekatan yang baik. Pada akhirnya error mudah berubah menjadi pekerjaan berulang yang hanya di-wrap lalu diteruskan ke level atas
    • “Error handling Go” sebenarnya sudah disediakan oleh sebagian besar bahasa, seperti bahasa fungsional, Rust, Java, dan lainnya, bukan cuma JavaScript atau Python. Pada akhirnya, selama ada generics, cara penanganan error ala Go bisa diimplementasikan di bahasa mana pun. Jika pembandingnya hanya JS atau Python, itu hanyalah pola yang umum
    • Justru poin “jika fungsi bisa gagal maka harus ditangani” itulah titik lemah Go. Di Go, error pada praktiknya bisa diabaikan sepenuhnya, jadi jika ingin membuat software yang benar-benar robust, cara Go malah bisa menjadi kelemahan
    • Ada komentar pahit bahwa Go2 pada akhirnya akan tetap jadi “laboratorium yang tidak akan pernah dirilis”
  • Awalnya saya kurang suka cara Go menangani error, tetapi setelah membaca posting blog errors-are-values dan mulai memakai panic(err) di tempat yang tepat, saya justru jadi sangat puas. Untuk kondisi abnormal yang memang tidak seharusnya ditangani langsung oleh kode induk, memakai panic bisa sangat mengurangi percabangan error yang berantakan di dalam kode. Cara mengelola error seperti ini sangat membantu dalam pekerjaan nyata saya

    • Ada bantahan bahwa logika seperti ini justru tidak bisa membela buruknya penanganan error di Go, dan walaupun diperbaiki, kelebihannya tidak akan hilang
    • Disebut juga bahwa PHP punya penanganan error per level atau penekanan error di call site dengan operator @, dan bash juga punya teknik pengelolaan error seperti -e
    • Saat pertama kali melihat alur try/catch/finally di C#, itu terasa segar, tetapi sekarang saya justru lebih menyukai logika sederhana seperti Go. Banyaknya baris kode (Loc) menurut saya tetap punya keunggulan karena alur kodenya lebih jelas
    • Disebutkan juga bahwa error berbasis sum type di Rust tetap termasuk dalam paradigma ‘errors are values’
  • Saat ada klaim bahwa kalau error benar-benar ditangani maka verbositasnya cepat tertutupi, saya jadi bertanya-tanya apakah membuat manual stack trace benar-benar termasuk ‘menangani’. Kalau mengikuti definisi Go, bukankah exception juga termasuk penanganan? Ada sanggahan bernada jenaka seperti itu

    • Saya ragu puluhan baris stack trace benar-benar informasi yang jelas. Secara pribadi saya merasa satu baris wrap error jauh lebih efisien dan juga membantu merapikan log. Setelah memakai Go lebih dari 10 tahun, saya tidak pernah membutuhkan informasi stack yang panjang, termasuk fungsi-fungsi runtime
  • Saya tidak suka tulisan ini membahas masalah error handling Go hanya sebagai “sintaksnya verbose”. Menurut saya masalah yang sebenarnya adalah 1) error mudah terlewat diam-diam atau terabaikan tanpa sengaja 2) hasil fungsi tidak bisa dengan mudah diteruskan atau disimpan seperti nilai biasa 3) error bertingkat seperti errors.Is terasa janggal dengan sistem tipe 4) sulit melakukan switching pada error 5) sentinel value banyak dipakai di standard library 6) kurang cocok dengan generics sehingga perlu paket tambahan, dan masih ada berbagai masalah lain

    • 90% programmer profesional Go menulis test case untuk setiap cabang return error demi memenuhi coverage, padahal di bahasa berbasis exception pekerjaan itu tidak perlu
    • Saya rasa klaim bahwa tulisan ini menjadikan It’s too verbose sebagai masalah utama tidak sesuai fakta. Mengubah sintaks pun tidak akan memberi banyak perbaikan yang benar-benar mendasar
    • Ada juga sudut pandang bahwa lambatnya laju perubahan Go (generics pun butuh waktu lama) justru merupakan keunggulan
    • Sebagai Googler, saya kembali kecewa pada keputusan tim Go
  • Di Elixir (dan Erlang), fungsi umumnya mengembalikan tuple {:ok, result} atau {:error, description}. Berkat sintaks with di Elixir, penanganan error bisa dikumpulkan di bagian bawah blok sehingga keterbacaannya jauh lebih baik. Jika Go juga memperkenalkan sesuatu yang mirip with, keterbacaan mungkin bisa ditingkatkan, misalnya dengan menjalankan rangkaian instruksi hanya saat error bernilai nil, lalu menaruh blok handler error di bagian paling bawah

    • Karena masalah konsensus komunitas, Go sangat lambat bahkan dalam mengadopsi fitur bernilai seperti sum type yang paling dasar, error handling, dan package management. Generics butuh 13 tahun, error handling 16 tahun, package management 9 tahun—perubahannya sangat lambat. Kehati-hatian memang penting, tetapi ada kekecewaan bahwa karena terus mengejar kesempurnaan, keputusan jadi selalu tertunda
    • Pola multiple return Go kadang juga dianggap tidak wajar tergantung sudut pandang. Kritiknya, satu-satunya hal yang bisa dilakukan fungsi yang mengembalikan banyak tipe hanyalah assignment ke variabel
  • Saya tidak mengerti kenapa Go tidak langsung mengikuti gaya Rust. Apalagi sekarang sudah ada generics, implementasi yang mirip pun semestinya cepat dibuat. Saya juga tidak setuju dengan logika yang mengkritik operator ? milik Rust sebagai sesuatu yang mendorong pengabaian error. Dalam praktiknya, Go justru sering membiarkan nilai return error diabaikan tanpa error kompilasi. Pencegahan kesalahan baru benar-benar mungkin jika pengembalian tipe Result dipaksa seperti gaya Rust. Kalau ini diperdebatkan atas nama kenyamanan, bukankah seharusnya panic juga dilarang? Itu argumen yang cukup keras

    • Ada pendapat bahwa alasan Go tidak bisa memperkenalkan Result adalah karena tidak ada sum type dan ada desain khas yang mewajibkan semua tipe punya zero value
    • Terhadap klaim bahwa fitur kenyamanan seperti “operator ?” akan membuat orang “tidak lagi memakai wrapped error”, ada bantahan bahwa justru fitur semacam itu bisa dirancang untuk mendorong wrapping
    • Sebagai kekurangan fitur yang menekankan kenyamanan (gaya Rust), dijelaskan bahwa alur percabangan jadi tersembunyi dalam satu baris, breakpoint debugging juga lebih sulit dipasang, dan fitur itu terlalu fokus pada bubbling daripada enrich/handling, sehingga termasuk jenis sintaks yang ditinggalkan Go (misalnya operator ternary)
    • Bahkan jika perbandingan gaya Rust diterapkan apa adanya, tetap muncul pertanyaan teknis: apa padanan yang benar-benar setara di Go?
    • Ada masukan yang meminta contoh kode: setelah generics masuk, sebenarnya implementasi gaya Rust seperti apa yang dimaksud?
  • Menurut saya bahasa tidak seharusnya dibahas dengan model mencentang fitur satu per satu seperti Rust, melainkan harus dirancang dalam konsistensi keseluruhan. Hanya karena semua item di daftar fitur sudah dicentang, bukan berarti itu otomatis cocok dengan hakikat bahasa tersebut

    • Muncul kesan bahwa Rust, karena bergerak dengan desain oleh komite, membuat sintaksnya sulit dibaca dan kurang konsisten
    • Ada pendapat bahwa “solusi sempurna” itu memang tidak ada
    • Hasil survei menunjukkan bahwa hanya 13% yang menjawab error handling sebagai satu masalah fatal utama Go, jadi sulit mengatakan itulah kelemahan tunggal yang menentukan. Tidak sedikit juga pengguna yang justru menyukai kondisi saat ini. Lihat hasil survei