Non-Fatal Error — adalah kesalahan yang tidak mengakibatkan penghentian aplikasi dan memungkinkan kelanjutan eksekusi program. Berbeda dengan fatal error, kesalahan non-fatal dapat ditangkap, ditangani, dan dicatat tanpa kehilangan sesi pengguna. Menurut Firebase Crashlytics Documentation, 2024, sekitar 70% dari semua kesalahan yang tercatat di aplikasi produksi bersifat non-fatal, tetapi mengabaikannya menyebabkan akumulasi utang teknis dan penurunan bertahap pengalaman pengguna. Penanganan kesalahan non-fatal yang benar adalah salah satu keterampilan kunci pengembang seluler.
Poin Penting
Non-Fatal Error — adalah pengecualian atau kondisi kesalahan yang tidak menyebabkan penghentian proses. Aplikasi terus berjalan, tetapi mungkin berada dalam kondisi yang tidak benar: data tidak dimuat, permintaan tidak terkirim, elemen antarmuka tidak ditampilkan. Pengguna mungkin tidak menyadari kesalahan atau melihat pesan dan melanjutkan penggunaan aplikasi.
Kesalahan non-fatal selalu memberi program jalur untuk pemulihan. Penangan kesalahan dapat menawarkan data alternatif, mengulangi operasi, atau menampilkan placeholder antarmuka. Tugas utamanya adalah mencegah crash dan mempertahankan pengalaman pengguna pada tingkat yang dapat diterima. Pengembang harus secara eksplisit merencanakan skenario pemulihan di setiap blok catch.
Menurut data Instabug 2024, 65% pengguna menghapus aplikasi setelah dua interaksi yang gagal. Kesalahan non-fatal yang diabaikan akan menumpuk dan menurunkan kualitas kerja secara keseluruhan. Pencatatan dan perbaikan sistematis kesalahan non-fatal adalah jalan langsung untuk meningkatkan retensi dan meningkatkan peringkat pengguna di toko aplikasi.
Kesalahan Jaringan — jenis kesalahan non-fatal yang paling umum di aplikasi seluler. Timeout koneksi, kehilangan jaringan, kode status server yang salah — semua situasi ini ditangkap dan ditangani tanpa crash. Pengguna ditampilkan pesan tentang ketidaktersediaan layanan dengan saran untuk mencoba lagi. Untuk kesalahan jaringan, pola retry dengan penundaan eksponensial adalah tipikal.
Format respons server yang salah, tidak adanya bidang wajib, tipe data yang salah — kesalahan parsing bersifat non-fatal jika aplikasi menangani data yang salah dengan benar. Pendekatan tipikal adalah menggunakan nilai cadangan default dan mencatat kesalahan parsing dengan konteks permintaan untuk analisis selanjutnya di server.
Masalah dengan pemuatan gambar, font yang salah, kesalahan tata letak — semuanya tidak fatal tetapi memperburuk pengalaman pengguna. Gambar placeholder dan nilai fallback memungkinkan menghindari layar kosong dan membuat kesalahan kurang terlihat. Di React Native untuk kesalahan UI digunakan Error Boundary dengan menampilkan komponen cadangan.
Kesalahan dalam perhitungan, ketidaksesuaian status, transisi yang salah antar layar — kesalahan logika seringkali tidak menyebabkan crash, tetapi menyebabkan perilaku aplikasi yang salah. Lebih sulit dideteksi tanpa pencatatan dan pemantauan sistematis karena tidak membuat laporan crash dan tetap tidak terlihat sampai ada keluhan pengguna.
Non-Fatal Error berbeda dari fatal karena memberi program kemampuan untuk terus bekerja. Fatal error — adalah kondisi dari mana aplikasi tidak dapat pulih: dereferensi pointer null, stack overflow, kehabisan memori. Kesalahan non-fatal dapat ditangkap, ditangani, dan eksekusi dilanjutkan, sementara fatal error memerlukan restart aplikasi.
| Karakteristik | Non-Fatal Error | Fatal Error |
|---|---|---|
| Penghentian Aplikasi | Tidak | Ya |
| Kemungkinan Pemulihan | Ya, melalui blok catch | Tidak |
| Pencatatan | Dari kode melalui recordException | Hanya oleh pelapor crash |
| Dampak UX | Ketidaknyamanan sementara | Kehilangan sesi total |
| Contoh | Network timeout, parse error | NullPointerException, OOM |
Batas antara non-fatal dan fatal dapat bergantung pada implementasi. Waktu tunggu jaringan di satu aplikasi ditangani sebagai non-fatal (mengulang permintaan setelah 1–2 detik), di aplikasi lain bisa menjadi fatal (crash jika tidak ada penangan). Penanganan kesalahan yang berkualitas mengubah situasi yang berpotensi fatal menjadi non-fatal, meningkatkan stabilitas aplikasi. Merancang sistem penanganan kesalahan adalah salah satu tugas arsitektur utama dalam pengembangan aplikasi seluler dengan persyaratan keandalan tinggi. Sistem pemantauan bawaan memungkinkan tim dengan cepat mendeteksi dan memperbaiki kesalahan non-fatal sebelum mempengaruhi sejumlah besar pengguna.
Firebase Crashlytics — alat utama untuk mencatat kesalahan non-fatal di aplikasi seluler. Metode recordException memungkinkan merekam pengecualian non-fatal dengan stack trace lengkap dan konteks eksekusi tanpa mengganggu kerja aplikasi. Berbeda dengan laporan crash, recordException dapat dipanggil di mana saja dalam kode untuk mencatat pengecualian yang ditangkap.
fun fetchUserData(userId: String) {
try {
val response = apiService.getUser(userId)
updateUI(response)
} catch (e: IOException) {
Crashlytics.log("Network error for user $userId")
Crashlytics.recordException(e)
showRetryDialog()
} catch (e: JsonParseException) {
// Non-fatal: menggunakan data cadangan
Crashlytics.recordException(e)
showFallbackContent()
}
}
// Pencatatan dengan kunci pengguna
Crashlytics.setCustomKey("screen", "Profile")
Crashlytics.setCustomKey("api_version", "v3")
Sentry — alternatif Crashlytics dengan diagnostik kesalahan non-fatal yang lebih detail. Sentry SDK menyediakan metode captureException yang mengirim detail pengecualian ke server. Keuntungan utama Sentry adalah pengelompokan kesalahan non-fatal serupa ke dalam satu issue, analisis frekuensi pengulangan, dan konteks eksekusi dalam bentuk breadcrumbs — urutan tindakan pengguna sebelum kesalahan.
Tidak semua kesalahan non-fatal perlu dicatat. Status yang diharapkan — kegagalan jaringan saat tidak ada koneksi — dapat dicatat secara selektif. Kesalahan yang tidak diharapkan — NullPointerException dalam kode yang ditangani, format data yang salah, logic error — harus selalu dicatat. Setiap tim menentukan ambang signifikansi: rata-rata 10 hingga 20 kesalahan non-fatal unik per 1000 pengguna per hari dianggap normal. Penting untuk mengatur peringatan pada peningkatan tajam jumlah kesalahan non-fatal — ini dapat menunjukkan masalah dengan versi API baru atau regresi setelah rilis.
Mekanisme penanganan dasar — try-catch, yang menangkap pengecualian dan menjalankan kode pemulihan. Untuk operasi jaringan, pola tipikal adalah mengulang permintaan dengan penundaan eksponensial (retry with backoff). Untuk kesalahan parsing — menggunakan nilai cadangan default dan mencatat konteks untuk analisis selanjutnya di sisi server.
func loadImage(from url: URL) -> UIImage? {
do {
let data = try Data(contentsOf: url)
return UIImage(data: data)
} catch {
Logger.shared.logError(error: "Image load failed: \(url)")
return UIImage(named: "placeholder")
}
}
func performRequest() async throws -> Data {
var lastError: Error? = nil
for attempt in 0..<3 {
do {
return try await URLSession.shared.data(from: url)
} catch {
lastError = error
try await Task.sleep(UInt64(pow(2, attempt)) * 1_000_000_000)
}
}
throw lastError ?? URLError(.unknown)
}
Tipe Result — pendekatan alternatif tanpa pengecualian. Fungsi mengembalikan sealed class Result dengan varian Success dan Failure. Kode pemanggil menangani kedua varian secara eksplisit, yang menghilangkan kesalahan yang tidak tertangani. Tipe Result populer di Kotlin (Result
Untuk setiap jenis kesalahan non-fatal perlu disediakan strategi pemulihan: memuat data dari cache saat kesalahan jaringan, menggunakan nilai default saat kesalahan parsing, menginisialisasi ulang komponen saat kesalahan UI. Praktik yang baik adalah menampilkan toast atau snackbar dengan pesan kesalahan kepada pengguna, tetapi tidak memblokir interaksi dengan aplikasi sepenuhnya. Penting untuk membedakan antara kesalahan yang dapat dipulihkan (recoverable) dan yang tidak dapat dipulihkan — untuk yang terakhir strategi pemulihan akan berbeda, misalnya, menyarankan untuk memulai ulang layar atau membersihkan data. Menyimpan cache status sukses sebelumnya seringkali menjadi cara paling sederhana dan paling efektif untuk menangani kesalahan non-fatal di platform seluler.
Pertanyaan yang Sering Diajukan
Warning — adalah peringatan dari kompiler atau penganalisis statis tentang potensi masalah dalam kode. Non-fatal error — adalah pengecualian runtime yang telah terjadi tetapi tidak menyebabkan crash. Warning dapat dihilangkan sebelum kompilasi, non-fatal error — ditangani selama eksekusi melalui blok catch.
Tidak, pencatatan berlebihan mengotori pemantauan. Sebaiknya mencatat kesalahan yang tidak diharapkan di produksi dan mengabaikan status yang diharapkan: kegagalan jaringan saat tidak ada koneksi dicatat secara selektif, sedangkan NullPointerException dalam kode yang ditangani — selalu. Setiap tim menentukan ambang signifikansi berdasarkan konteks aplikasi.
Di SwiftUI digunakan ObservableObject dengan bidang @Published errorState untuk melacak status kesalahan. View berlangganan perubahan dan menampilkan konten alternatif. Sebelum iOS 17 digunakan Combine dengan penangan, mulai iOS 17 — SwiftData dan makro @Observable untuk pembaruan UI reaktif.
Ya, jika kesalahan menyebabkan reaksi berantai. Contoh: kegagalan non-fatal saat memuat gambar dapat menyebabkan status UI yang salah, yang kemudian menyebabkan crash saat mencoba menampilkan. Penanganan kesalahan non-fatal yang berkualitas di setiap level mencegah eskalasinya ke level fatal.
Di iOS, kesalahan non-fatal ditangani melalui do-catch dengan throw, di Android — melalui try-catch dengan pengecualian. iOS menggunakan NSError dengan domain dan kode kesalahan, Android — pengecualian Java/Kotlin. Crashlytics bekerja sama di kedua platform melalui recordException, menyediakan antarmuka terpadu untuk pemantauan.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga