Non-Fatal Error در برنامه‌های موبایل — ماهیت، انواع و مدیریت خطا

نویسنده: IT Sectr منتشر شده: 2026-05-27 زمان مطالعه: 8 دقیقه

Non-Fatal Error — خطایی است که منجر به پایان کار برنامه نمی‌شود و امکان ادامه اجرای برنامه را فراهم می‌کند. برخلاف fatal error، خطاهای غیربحرانی می‌توانند بدون از دست دادن جلسه کاربر گرفته، مدیریت و لاگ شوند. طبق داده‌های Firebase Crashlytics Documentation, 2024، حدود 70٪ از تمام خطاهای ثبت‌شده در برنامه‌های production غیربحرانی هستند، اما نادیده گرفتن آن‌ها منجر به انباشت بدهی فنی و بدتر شدن تدریجی تجربه کاربری می‌شود. مدیریت صحیح خطاهای non-fatal یکی از مهارت‌های کلیدی توسعه‌دهنده موبایل است.

نکات اصلی

  • Non-Fatal Error — خطایی که برنامه را خاتمه نمی‌دهد و امکان بازیابی اجرا را فراهم می‌کند
  • مدیریت خطاهای غیربحرانی شامل try-catch، لاگ کردن و نمایش fallback UI است
  • لاگ کردن خطاهای non-fatal برای یافتن باگ‌های پنهان در production حیاتی است
  • Fatal Error — نقطه مقابل: خطایی که باعث crash برنامه بدون امکان بازیابی می‌شود
  • Crashlytics و Sentry امکان ردیابی خطاهای non-fatal را در زمان واقعی فراهم می‌کنند

Non-Fatal Error چیست

Non-Fatal Error — یک استثنا یا حالت خطایی است که باعث خاتمه فرآیند نمی‌شود. برنامه به کار خود ادامه می‌دهد، اما ممکن است در وضعیت نادرستی قرار گیرد: داده‌ها بارگیری نشدند، درخواست ارسال نشد، عنصر رابط کاربری نمایش داده نشد. کاربر یا متوجه خطا نمی‌شود یا پیامی را می‌بیند و به استفاده از برنامه ادامه می‌دهد.

ویژگی‌های کلیدی

خطای غیربحرانی همیشه راهی برای بازیابی در اختیار برنامه قرار می‌دهد. مدیریت‌کننده خطا می‌تواند داده‌های جایگزین ارائه دهد، عملیات را تکرار کند یا یک placeholder رابط کاربری نشان دهد. وظیفه اصلی جلوگیری از crash و حفظ تجربه کاربری در سطح قابل قبول است. توسعه‌دهنده باید صریحاً سناریوی بازیابی را در هر بلوک catch پیش‌بینی کند.

نقش در پایداری برنامه‌ها

طبق داده‌های Instabug 2024، 65٪ از کاربران پس از دو تعامل ناموفق برنامه را حذف می‌کنند. خطاهای non-fatal که بدون توجه رها می‌شوند، انباشته شده و کیفیت کلی کار را کاهش می‌دهند. لاگ کردن سیستماتیک و رفع خطاهای غیربحرانی مسیری مستقیم برای افزایش retention و بهبود امتیازات کاربران در فروشگاه‌های برنامه است.

انواع خطاهای غیربحرانی

خطاهای شبکه — رایج‌ترین نوع خطاهای non-fatal در برنامه‌های موبایل. زمان انتظار اتصال، قطع شبکه، کد وضعیت نادرست سرور — همه این موارد بدون crash گرفته و مدیریت می‌شوند. به کاربر پیامی درباره عدم دسترسی به سرویس با پیشنهاد تلاش مجدد نمایش داده می‌شود. برای خطاهای شبکه، الگوی retry با تأخیر نمایی معمول است.

خطاهای اعتبارسنجی داده

فرمت نادرست پاسخ سرور، عدم وجود فیلد اجباری، نوع داده نادرست — خطاهای تجزیه اگر برنامه داده‌های نادرست را به درستی مدیریت کند، غیربحرانی هستند. رویکرد معمول استفاده از مقادیر پیش‌فرض جایگزین و لاگ کردن خطای تجزیه با زمینه درخواست برای تحلیل بعدی در سرور است.

خطاهای رندر UI

مشکلات بارگیری تصاویر، فونت‌های نادرست، خطاهای layout — همه اینها بحرانی نیستند، اما تجربه کاربر را بدتر می‌کنند. تصاویر جایگزین و مقادیر fallback از نمایش صفحه‌های خالی جلوگیری کرده و خطاها را کمتر قابل توجه می‌کنند. در React Native برای خطاهای UI از Error Boundary با نمایش کامپوننت جایگزین استفاده می‌شود.

خطاهای منطق کسب‌وکار و حالت

خطا در محاسبات، ناهماهنگی حالت‌ها، انتقال‌های نادرست بین صفحه‌ها — خطاهای منطقی اغلب منجر به crash نمی‌شوند، اما باعث رفتار نادرست برنامه می‌شوند. تشخیص آن‌ها بدون لاگ کردن و نظارت سیستماتیک دشوارتر است، زیرا گزارش crash ایجاد نمی‌کنند و تا شکایت کاربر نادیده می‌مانند.

Non-Fatal Error در مقابل Fatal Error: مقایسه

Non-Fatal Error با fatal تفاوت دارد از این جهت که به برنامه امکان ادامه کار می‌دهد. Fatal error — حالتی است که برنامه نمی‌تواند از آن بازیابی کند: dereference اشاره گر null، سرریز پشته، کمبود حافظه. خطای non-fatal قابل گرفتن، مدیریت و ادامه اجراست، در حالی که fatal error نیاز به راه‌اندازی مجدد برنامه دارد.

ویژگیNon-Fatal ErrorFatal Error
خاتمه برنامهخیربله
امکان بازیابیبله، از طریق بلوک catchخیر
لاگ کردناز کد از طریق recordExceptionفقط توسط گزارشگر crash
تأثیر بر UXناراحتی موقتاز دست دادن کامل جلسه
مثالNetwork timeout, parse errorNullPointerException, OOM

مرز بین non-fatal و fatal می‌تواند به پیاده‌سازی بستگی داشته باشد. تایم‌اوت شبکه در یک برنامه به عنوان non-fatal مدیریت می‌شود (تکرار درخواست پس از ۱–۲ ثانیه)، در دیگری ممکن است fatal باشد (crash در صورت نبود مدیریت‌کننده). مدیریت باکیفیت خطاها، موقعیت‌های بالقوه fatal را به غیربحرانی تبدیل کرده و پایداری برنامه را افزایش می‌دهد. طراحی سیستم مدیریت خطا یکی از وظایف معماری کلیدی در توسعه برنامه موبایل با الزامات بالای قابلیت اطمینان است. سیستم نظارت داخلی به تیم امکان می‌دهد خطاهای غیربحرانی را قبل از تأثیر بر تعداد قابل توجهی از کاربران به سرعت کشف و رفع کند.

لاگ کردن خطاهای non-fatal

Firebase Crashlytics — ابزار اصلی برای لاگ کردن خطاهای غیربحرانی در برنامه‌های موبایل. متد recordException به شما امکان می‌دهد یک استثنای non-fatal را با stack trace کامل و زمینه اجرا بدون قطع کار برنامه ثبت کنید. برخلاف گزارش‌های crash، recordException را می‌توان در هر جایی از کد برای لاگ کردن استثناهای گرفته‌شده فراخوانی کرد.

kotlin
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: از داده‌های جایگزین استفاده می‌کنیم
        Crashlytics.recordException(e)
        showFallbackContent()
    }
}

// لاگ کردن با کلیدهای کاربر
Crashlytics.setCustomKey("screen", "Profile")
Crashlytics.setCustomKey("api_version", "v3")

Sentry — جایگزینی برای Crashlytics با تشخیص دقیق‌تر خطاهای non-fatal. SDK Sentry متد captureException را ارائه می‌دهد که جزئیات استثنا را به سرور ارسال می‌کند. مزیت کلیدی Sentry گروه‌بندی خطاهای non-fatal مشابه در یک issue، تحلیل فراوانی تکرار و زمینه اجرا به صورت breadcrumbs — توالی اقدامات کاربر قبل از خطا — است.

معیارهای لاگ کردن خطاهای non-fatal

همه خطاهای non-fatal نیازی به لاگ شدن ندارند. حالات مورد انتظار — عدم وجود شبکه هنگام قطع اتصال — می‌توانند انتخابی لاگ شوند. خطاهای غیرمنتظره — NullPointerException در کد مدیریت‌شده، فرمت نادرست داده، logic error — باید همیشه لاگ شوند. هر تیم آستانه اهمیت را تعیین می‌کند: به طور متوسط ۱۰ تا ۲۰ خطای non-fatal منحصربه‌فرد به ازای ۱۰۰۰ کاربر در روز نرمال در نظر گرفته می‌شود. مهم است که هشدارهایی برای افزایش ناگهانی تعداد خطاهای non-fatal تنظیم کنید — این می‌تواند نشان‌دهنده مشکلات با نسخه جدید API یا پسرفت پس از انتشار باشد.

مدیریت خطاهای non-fatal در کد

مکانیزم اصلی مدیریت — try-catch که استثنا را گرفته و کد بازیابی را اجرا می‌کند. برای عملیات شبکه، الگوی معمول تکرار درخواست با تأخیر نمایی (retry with backoff) است. برای خطاهای تجزیه — استفاده از مقادیر پیش‌فرض جایگزین و لاگ کردن زمینه برای تحلیل بعدی در سمت سرور.

swift
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)
}

انواع Result — رویکرد جایگزین بدون استثنا. تابع یک sealed class Result با گزینه‌های Success و Failure برمی‌گرداند. کد فراخوان هر دو گزینه را به صراحت مدیریت می‌کند که خطاهای مدیریت‌نشده را حذف می‌کند. انواع Result در Kotlin (Result در کتابخانه استاندارد) و Swift (Result) برای مدیریت صریح حالات non-fatal در سطح انواع محبوب هستند.

استراتژی‌های Fallback برای خطاهای non-fatal

برای هر نوع خطای non-fatal باید استراتژی بازیابی در نظر گرفته شود: بارگیری داده‌های کش شده هنگام خطای شبکه، استفاده از مقادیر پیش‌فرض هنگام خطای تجزیه، راه‌اندازی مجدد کامپوننت هنگام خطای UI. روش خوب نمایش toast یا snackbar با پیام خطا به کاربر است، اما نه مسدود کردن کامل تعامل با برنامه. مهم است بین خطاهای قابل بازیابی (recoverable) و غیرقابل بازیابی تمایز قائل شوید — برای دومی استراتژی بازیابی متفاوت خواهد بود، مثلاً پیشنهاد راه‌اندازی مجدد صفحه یا پاک کردن داده‌ها. کش کردن وضعیت موفق قبلی اغلب ساده‌ترین و مؤثرترین روش برای مدیریت خطاهای non-fatal در پلتفرم‌های موبایل است.

سوالات متداول

تفاوت خطای non-fatal با warning چیست؟

Warning — هشداری از سوی کامپایلر یا تحلیلگر ایستا درباره یک مشکل بالقوه در کد است. Non-fatal error — یک استثنای زمان اجراست که قبلاً رخ داده اما منجر به crash نشده است. Warning را می‌توان قبل از کامپایل برطرف کرد، non-fatal error — در طول اجرا از طریق بلوک catch مدیریت کرد.

آیا باید همه خطاهای non-fatal را لاگ کرد؟

خیر، لاگ کردن بیش از حد مانیتورینگ را شلوغ می‌کند. بهتر است خطاهای غیرمنتظره را در production لاگ کرده و حالات مورد انتظار را نادیده بگیرید: عدم شبکه هنگام قطع اتصال به صورت انتخابی لاگ می‌شود، اما NullPointerException در کد مدیریت‌شده — همیشه. هر تیم آستانه اهمیت را بر اساس زمینه برنامه تعیین می‌کند.

چگونه خطای non-fatal را در SwiftUI مدیریت کنیم؟

در SwiftUI از ObservableObject با فیلد @Published errorState برای ردیابی حالت خطا استفاده می‌شود. View تغییرات را دنبال کرده و محتوای جایگزین نمایش می‌دهد. قبل از iOS 17 از Combine با مدیریت‌کننده‌ها استفاده می‌شد، از iOS 17 به بعد — SwiftData و ماکروهای @Observable برای به‌روزرسانی واکنشی UI.

آیا خطای non-fatal می‌تواند fatal شود؟

بله، اگر خطا واکنش زنجیره‌ای ایجاد کند. مثال: خرابی غیربحرانی بارگیری تصویر می‌تواند منجر به حالت نادرست UI شود که سپس هنگام تلاش برای نمایش باعث crash می‌شود. مدیریت باکیفیت خطاهای non-fatal در هر سطح از escalation آن‌ها به سطح fatal جلوگیری می‌کند.

تفاوت non-fatal در iOS و Android چیست؟

در iOS خطاهای non-fatal از طریق do-catch با throw مدیریت می‌شوند، در Android — از طریق try-catch با استثناها. iOS از NSError با دامنه‌ها و کدهای خطا استفاده می‌کند، Android — از استثناهای Java/Kotlin. Crashlytics در هر دو پلتفرم به طور یکسان از طریق recordException کار می‌کند و رابط یکپارچه‌ای برای نظارت فراهم می‌کند.

خلاصه

  • Non-Fatal Error — خطای زمان اجرا که برنامه را خاتمه نمی‌دهد و امکان بازیابی اجرا را فراهم می‌کند
  • خطاهای شبکه، تجزیه و رندر UI — سه دسته اصلی خطاهای غیربحرانی
  • Fatal Error — نقطه مقابل non-fatal که باعث crash کامل برنامه بدون بازیابی می‌شود
  • Crashlytics و Sentry — ابزارهای اصلی لاگ کردن خطاهای non-fatal در production
  • انواع Result — جایگزینی برای استثناها برای مدیریت صریح حالات خطا در سطح انواع
  • مقادیر جایگزین و استراتژی‌های fallback از بدتر شدن قابل مشاهده تجربه کاربری جلوگیری می‌کنند
  • رفع سیستماتیک خطاهای non-fatal retention و کیفیت برنامه را طبق Instabug افزایش می‌دهد

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید