GoSuda

Alasan Go memilih pengembalian error eksplisit dan panic-recover alih-alih melempar exception dengan try-catch

By Rabbit Princess views ...

Go secara sengaja tidak mendukung try-catch, dan hanya menyediakan sintaks panic-recover. Hal ini menjadi keluhan dari banyak pengembang yang sudah terbiasa dengan penanganan error menggunakan try-catch. Lalu, mengapa try-catch tidak disertakan? Itu karena try-catch memiliki berbagai permasalahan.

try-catch-finally

Sintaks try-catch (trait-catch) adalah sintaks untuk menangani kondisi error dan kondisi eksepsional yang dapat terjadi selama program dijalankan (runtime). Selain itu, finally digunakan untuk menuliskan kode yang harus selalu dieksekusi, terlepas dari ada atau tidaknya pengecualian yang terjadi.

Penanganan Error dan Tanggung Jawab

Pada tahun 1980-an dan 1990-an, penanganan error sangat sederhana. Pesan error hanya berupa "disk floppy penuh", "tidak ada disk floppy di drive", dan "tidak memiliki izin tulis ke disk floppy". Pada masa itu, ketika error terjadi, pengembang melakukan throw terhadap error tersebut hingga ke titik penanganan error, sehingga penanganannya dapat dibuat terpusat. Dalam situasi seperti ini, sintaks try-catch bekerja dengan efisien.

Namun, seiring berjalannya waktu, situasinya berubah. Logika bisnis menjadi semakin kompleks, muncul basis data dan transaksi, aplikasi harus memanggil banyak API melalui jaringan sambil menginterpretasikan banyak pesan request, dan bahkan dengan munculnya pemrograman konkuren, error harus ditangani pada thread selain thread utama.

Error menjadi terlalu kompleks untuk ditangani di satu tempat, dan tidak ada satu lokasi pun yang dapat bertanggung jawab atas seluruh error. Di sinilah try-catch menghadapi masalah serius.

Pelimpahan Tanggung Jawab pada try-catch

Singkatnya, try-catch adalah cara bagi entitas yang memunculkan error untuk melimpahkan tanggung jawab atas error tersebut (pembersihan lanjutan) kepada pihak lain. Pihak yang dilimpahi dapat berupa blok catch, method induknya, atau salah satu dari induk-induk di atasnya yang entah siapa. Dengan kata lain, dalam dunia dengan penanganan error yang semakin banyak dan kompleks, pendekatan yang dipilih try-catch adalah "pasti ada yang akan menanganinya". Perhatikan kode berikut.

1try {
2    data = readFile("hello.txt");
3    structuredData = parseData(data);
4    insertDBStatus(structuredData[1]);
5    startHTTPServer(structuredData[2]);
6} catch (Exception e) {
7    e.printStackTrace();
8}

Masalah pada kode di atas adalah tidak jelas siapa yang bertanggung jawab memproses printStackTrace, dan kita juga tidak dapat mengetahui bagian kode mana yang menyebabkan error. Terlebih lagi, semakin banyak logika di dalam pernyataan try, masalahnya menjadi semakin mengerikan. Namun, ironisnya, semakin kompleks pengembangan, semakin para pengembang terjerat pada try-catch yang melimpahkan tanggung jawab. Mereka berhenti memikirkan penanganan error, kesadaran akan tanggung jawab pun memudar, dan pada akhirnya mereka melupakan hakikat penanganan error dan eksepsi. Lalu, bagaimana golang mengatasi masalah ini?

panic, recover

Salah satu keunggulan Go adalah adanya berbagai sistem yang membantu pengembang menjadi pengembang yang baik, bukan membawa mereka ke jalan yang keliru. panic-recover juga dapat dijadikan contoh dari hal ini.

Sekilas, panic-recover tampak tidak berbeda dengan try-catch, tetapi keduanya berbeda dalam hal bahwa ketika terjadi masalah, tanggung jawab tidak dilimpahkan ke luar. Di Go, ketika panic terjadi, penanganannya harus dilakukan di lokasi tempat panic tersebut terjadi, alih-alih meneruskan nilainya ke luar. Hal ini memberikan tanggung jawab penanganan error kepada pengembang dan mendorong mereka untuk memikirkan secara lebih mendalam di mana, oleh siapa, dan bagaimana error tersebut harus ditangani. Ini seperti memberikan otonomi kepada pengguna sambil tetap menyisakan ruang untuk berpikir.

Pemilihan kata panic juga dapat dikatakan sangat tepat. Berbeda dengan try-recover, panic-recover dengan sendirinya memberikan tekanan kepada pengembang bahwa penggunaannya hanya boleh dilakukan pada kondisi error yang jelas, bukan pada kondisi eksepsional. Secara alami, pengembang tidak akan menyalahgunakan recover dan hanya menggunakannya di tempat yang memang diperlukan. Hal ini sangat membantu dalam menulis kode yang ringkas di Go.