Satu Baris Catch yang Menghapus Sesi Admin
Kegagalan API dan sesi kedaluwarsa diperlakukan sama oleh satu catch, sampai server restart meng logout semua admin sekaligus.
Ringkasan
Bug satu baris bikin semua admin terlempar ke login tiap server restart, gara-gara satu catch nganggep outage sama kayak token kedaluwarsa. Solusinya simpel: purge token cuma kalau responsnya 401, sisanya ditahan pakai banner retry. Lima unit test ngunci klasifikasinya, jadi logout otomatis nggak kejadian cuma karena server sempat down.
Backend API restart sebentar, dan seluruh admin yang sedang masuk otomatis terlempar ke halaman login. Tanpa pesan, tanpa peringatan. Sesi yang masih valid dianggap kedaluwarsa hanya karena server sempat tidak bisa dihubungi.
Pemicunya satu baris. Bootstrap sesi di shell admin punya catch tunggal: kegagalan apa pun langsung menghapus token tersimpan. Respons 5xx, koneksi putus, atau sesi yang memang kedaluwarsa semuanya diperlakukan identik. Gangguan sesaat di server terlihat persis seperti logout.
Mengapa satu catch tidak cukup
Kesalahan umumnya bukan tidak ada penanganan, melainkan penanganan yang tidak membedakan identitas kegagalan. Spesifikasi fetch di MDN menjelaskan perbedaan jalurnya secara tegas: promise fetch hanya menolak ketika permintaan gagal di jaringan atau URL-nya tidak valid; respons dengan status HTTP error justru menyelesaikan promise secara normal, dan pemeriksaan status dilakukan lewat properti respons [6]. Artinya outage dan 401 tiba lewat dua pintu berbeda, dan memperlakukan keduanya sama di satu catch berarti membuang informasi itu.
Dari sisi keamanan, menghapus sesi ketika server mengembalikan 5xx bukan sikap hati-hati. OWASP menuliskan bahwa mekanisme keamanan sebaiknya gagal lewat jalur yang sama dengan penolakan [2], tetapi yang terjadi di sini berbeda: sesi valid dihancurkan karena gangguan infrastruktur. Itu bukan fail-closed yang melindungi, melainkan salah klasifikasi yang menghukum pengguna.
401, 403, dan 5xx tiga perlakuan
Perbaikannya dimulai dengan fungsi klasifikasi shouldClearSession: token hanya dihapus ketika error adalah AdminApiError dengan status 401. MDN mendefinisikan 401 sebagai respons ketika permintaan tidak punya kredensial autentikasi yang valid [4]. Hanya skenario itu yang membenarkan penghapusan otomatis, karena identitas memang tidak bisa diverifikasi lagi.
403 diperlakukan lain. Server memahami permintaan tetapi menolaknya, dan MDN mencatat bahwa mengulang permintaan tanpa modifikasi akan gagal dengan cara yang sama [5]. Karena itu 403 tidak boleh memicu percobaan ulang, juga tidak boleh menghapus token yang sebenarnya valid. Antarmuka menampilkan pemberitahuan akses ditolak dengan tombol keluar yang eksplisit ke halaman login.
5xx dan kegagalan jaringan murni mendapat perlakuan ketiga: sesi dipertahankan. Panel menampilkan banner non-fatal berisi tombol coba lagi yang menjalankan ulang bootstrap. Begitu server pulih, admin kembali ke dasbor tanpa mengetik ulang kredensial.
Lima test mengunci klasifikasi
Klasifikasi semudah ini juga tetap butuh pengunci. Lima kasus unit test mencakup spektrumnya: 401 mengembalikan true; 403, 500, TypeError kegagalan jaringan, dan nilai undefined semuanya mengembalikan false. Daftar ini membuat satu pola tersurat bagi pengembang berikutnya: memperluas perilaku purge membutuhkan alasan eksplisit dan test yang menemani.
Ada satu detail implementasi yang mudah terlewat: pembeda 401 dan sisanya hidup di satu fungsi kecil, bukan tersebar di layout. Komponen layout cukup bertanya pada fungsi itu, lalu memilih antara tiga render: halaman login, banner akses ditolak, atau banner outage dengan tombol coba lagi. Logika keputusan yang terpusat itulah yang membuat lima test bisa ditulis tanpa menyentuh DOM sekalipun.
Pengalaman di lapangan juga menunjukkan pola gangguannya: outage jarang datang sendirian, dan retry yang berani berarti admin tidak perlu membersihkan localStorage manual atau mengingat-ingat URL dashboard saat server pulih.
Kontra pengetesan yang bisa dilakukan siapa pun: matikan backend sebentar sambil membuka panel admin, lalu amati. Versi dengan catch tunggal langsung melempar ke login. Versi berklasifikasi menahan layar di banner dan menyambungkan lagi sesi begitu server hidup.
Sisi keamanannya juga jujur: purge hanya di 401 bukan longgar, melainkan lebih presisi. Token yang dicabut server tetap terhapus dari penyimpanan lokal pada request pertama yang menabrak 401. Yang berubah hanyalah nasib sesi ketika yang bermasalah bukan kredensial.
Escalation path-nya tertib. 401 dijawab dengan layar login tanpa drama. 403 dijawab dengan kebenaran yang menyakitkan: akun ini memang tidak punya akses, dan menunggu tidak akan mengubahnya. 5xx dijawab dengan kesabaran: masalahnya di server, bukan di Anda.
Perbedaan 401 dan 403 memang sering tertukar, dan konsekuensinya jarang terlihat sampai server benar-benar bermasalah. Mengklasifikasikan kegagalan sebelum bertindak mengubah pengalaman gangguan dari kejutan menjadi prosedur: kredensial bermasalah disiksa sesingkat mungkin, infrastruktur yang sedang gangguan diberi ruang untuk pulih.Sources: