مدیریت خطا یک مهارت اساسی برای توسعهدهنده موبایل است. طبق HackerOne (2025)، 62٪ از نشت دادهها به دلیل استثناهای مدیریتنشده رخ میدهد. مدیریت صحیح خطا نه تنها از کرشها جلوگیری میکند، بلکه از دادههای کاربر نیز محافظت میکند. بیایید رویکردهای iOS، Android و React Native را بررسی کنیم.
نکات کلیدی
مدیریت خطا در Swift بر چهار مکانیسم کلیدی ساخته شده است: do-catch، throws، guard let و if-let. برخلاف بسیاری از زبانها، Swift استثناهای گرفتهنشده را مجاز نمیداند — هر خطا باید به صراحت مدیریت یا از طریق throws اعلام شود. مدیریت خطا یک مهارت حیاتی برای توسعه موبایل است که مستقیماً بر پایداری برنامه تأثیر میگذارد.
do-catch بلوک استاندارد برای فراخوانی توابع علامتگذاری شده با throws است. در داخل do، یک تابع با try فراخوانی میشود و اگر خطایی پرتاب کند، کنترل به catch منتقل میشود. انواع مختلف خطا را میتوان از طریق pattern matching مدیریت کرد. اگر خطایی مدیریت نشود، به بالای پشته propagates میشود (Error Propagation). برای مدیریت مؤثر خطا در iOS، از do-catch به عنوان مکانیسم اصلی استفاده کنید.
Throw در امضای تابع اعلام میشود: func fetchData() throws -> Data. این بدان معناست که کد فراخوان باید خطا را از طریق try، try? یا try! مدیریت کند. try? خطا را به nil تبدیل میکند، try! در صورت خطا باعث کرش میشود (فقط در صورت اطمینان از موفقیت استفاده کنید). مدیریت خطا از طریق throw یک روش اجباری در Swift است.
Guard let ساختاری برای خروج زودهنگام از تابع در صورت nil بودن مقدار است. برخلاف if-let، guard let در شاخه else به یک خروج (return، throw، break) نیاز دارد. این کار کد را صافتر و خواناتر میکند — بدون بلوکهای if تودرتو. اگر یک optional نمیتواند nil باشد — از force unwrap (!) استفاده کنید، فقط زمانی که کاملاً مطمئن هستید. در یک برنامه موبایل، guard let به جلوگیری از کرشها هنگام مدیریت مقادیر اختیاری کمک میکند.
Optional Chaining (user?.address?.city) و nil-coalescing (??) شکر نحوی برای کار با optionals بدون باز کردن هستند. در IT Sectr، ما از guard let برای اعتبارسنجی پارامترهای ورودی API استفاده میکنیم و تیم را ملزم میکنیم بدون توضیح صریح از force unwrap اجتناب کنند. یک مدیریتکننده خطا در هر سطح از خرابیهای غیرمنتظره محافظت میکند.
Kotlin زبان اصلی برای توسعه Android است. try-catch را از Java به ارث میبرد اما جایگزینهای امنتری اضافه میکند: عملگر elvis، require، check و sealed class. مدیریت خطا در Kotlin بر اساس ترکیبی از این مکانیسمها ساخته شده است. برخلاف Swift، Kotlin به مدیریت استثناهای بررسیشده نیاز ندارد (همه استثناها بررسینشده هستند). برای مدیریت خطا در برنامههای موبایل در Android، از sealed class به عنوان الگوی اصلی استفاده کنید.
Try-catch در Kotlin به عنوان یک عبارت عمل میکند — یک مقدار برمیگرداند. val result = try { fetchData() } catch (e: Exception) { fallbackValue }. این کار کد را کوتاه میکند. عملگر Elvis (?:) مشابه nil-coalescing برای انواع nullable است: val name = user?.name ?: "Guest". برای مدیریت خطا در برنامههای موبایل، try-catch به عنوان یک عبارت مختصرترین رویکرد است.
Sealed class ابزاری قدرتمند برای مدلسازی حالات موفقیت و خطا است. sealed class NetworkResult { data class Success(val data: T) : NetworkResult(); data class Error(val message: String) : NetworkResult() }. وقتی در عبارت when استفاده میشود، کامپایلر کامل بودن شاخهها را بررسی میکند. مدیریت خطا از طریق sealed class تضمین میکند که هیچ حالتی بدون مدیریت باقی نمیماند.
// Sealed class + try-catch — الگوی معمولی برای Android
sealed class NetworkResult<out T> {
data class Success<out T>(val data: T) : NetworkResult<T>()
data class Error(val message: String) : NetworkResult<Nothing>()
}
fun fetchUser(id: String): NetworkResult<User> {
return try {
NetworkResult.Success(api.getUser(id))
} catch (e: Exception) {
NetworkResult.Error("Failed: ${e.message}")
}
}
در مثال، sealed class NetworkResult دو حالت را مدل میکند: موفقیت با داده و خطا با پیام. تابع fetchUser در هر صورت یک نتیجه برمیگرداند و کد فراخوان هر دو شاخه را از طریق when مدیریت میکند. این احتمال خطای مدیریتنشده را از بین میبرد. مدیریت خطا از طریق sealed class استاندارد توسعه Android در IT Sectr است.
Result یک نوع داخلی Kotlin برای نمایش نتیجه عملیاتی است که ممکن است شکست بخورد. این نوع مدیریت موفقیت و شکست را از طریق fold، getOrThrow یا map اجباری میکند. Result در زنجیرههای ناهمگام (coroutines) مفید است. مدیریت خطا با Result استانداردی برای توسعه موبایل در Kotlin است.
Either یک نوع تابعی از کتابخانه Arrow است که اجازه میدهد مقداری از یکی از دو نوع برگردانده شود (Left — خطا، Right — موفقیت). برخلاف Result، Either میتواند هر نوع خطای تعریفشده توسط کاربر را شامل شود. برای پروژههای ساده، Result داخلی کافی است؛ برای پروژههای پیچیده، از Either از Arrow استفاده کنید. انتخاب ابزار مدیریت خطا به پیچیدگی پروژه بستگی دارد.
انتشار خطا مکانیسمی است که در آن یک خطا تا زمانی که مدیریت شود، به بالای پشته فراخوانی propagates میشود. در Kotlin، این به طور پیشفرض اتفاق میافتد (استثناهای بررسینشده). در Swift، این فقط برای توابع علامتگذاری شده با throws اعمال میشود. با Result و Either، خطاها منتشر نمیشوند — آنها در نوع باقی میمانند و شما باید آنها را مدیریت کنید. این کار مدیریت خطا را در برنامههای موبایل ایمنتر میکند.
| پارامتر | iOS (Swift) | Android (Kotlin) |
|---|---|---|
| مکانیسم پایه | do-catch + throws | try-catch (expression) |
| Optional/Nullable | guard let, if-let, ?? | ?. let, elvis (?:) |
| رویکرد تابعی | Result (Swift 5+) | Result, Either (Arrow) |
| مدلسازی خطا | Enum: Error | Sealed class |
| استثناهای بررسیشده | بله (throws) | خیر (همه بررسینشده) |
| Non-fatal | os_log, Crashlytics | Timber, Crashlytics |
جدول تفاوتهای کلیدی را نشان میدهد. iOS به اعلام صریح خطا (throws) نیاز دارد که کد را ایمنتر اما پرگفتارتر میکند. Android به انضباط توسعهدهنده متکی است. در IT Sectr، ما از sealed class برای Android و throws برای iOS استفاده میکنیم — این بهترین روش هر دو پلتفرم برای مدیریت خطا در برنامههای موبایل است.
گزارش کرش سیستمی برای جمعآوری و تحلیل کرشهای برنامه است. گزارش کرش بخش ضروری مدیریت خطا در محیط تولید است. بدون آن، شما مشکلات را از کاربران مطلع میشوید که برای تولید غیرقابل قبول است. دو ابزار اصلی: Firebase Crashlytics (رایگان) و Sentry (رایگان برای استفاده پایه). برای مدیریت خطا در برنامههای موبایل، همیشه از اولین انتشار گزارش کرش را پیادهسازی کنید.
Crashlytics بخشی از Firebase است. به طور خودکار کرشها را جمعآوری میکند، آنها را بر اساس پشته فراخوانی گروهبندی میکند و تعداد کاربران آسیبدیده را نشان میدهد. از ثبت خطاهای غیرکشنده از طریق recordException() پشتیبانی میکند. یکپارچهسازی: SDK را به build.gradle (Android) یا Podfile (iOS) اضافه کنید. Crashlytics بهترین ابزار رایگان برای مدیریت خطا در شروع پروژه است.
Sentry یک سیستم نظارت بر خطاهای چندپلتفرمی است. برخلاف Crashlytics، Sentry ردیابی جزئیات (breadcrumbs)، نظارت بر عملکرد و پشتیبانی React Native را فراهم میکند. این امکان را میدهد که وضعیت برنامه را در لحظه خطا مشاهده کنید. IT Sectr Sentry را برای پروژههایی که نیاز به کنترل کامل بر مدیریت خطا در توسعه موبایل دارند، توصیه میکند.
Error Boundary یک کامپوننت React است که خطاهای JavaScript را در درخت کامپوننتهای فرزند میگیرد و یک رابط کاربری جایگزین نشان میدهد و از کرش کامل برنامه جلوگیری میکند. Error Boundary یک کامپوننت کلیدی برای مدیریت خطا در React Native است. از error boundaries برای صفحههای حیاتی و ناوبری استفاده کنید. مدیریت خطا در برنامههای موبایل در React Native نیاز به راهاندازی مناسب Error Boundary در سطح بالایی دارد.
Error Boundary از طریق componentDidCatch(error, errorInfo) یا static getDerivedStateFromError(error) ایجاد میشود. این کامپوننت خطاهای کد ناهمگام (setTimeout, requestAnimationFrame)، رندر سمت سرور یا خطاهای بومی (Native Modules) را نمیگیرد. برای ثبت، از SDK گزارش کرش درون componentDidCatch استفاده کنید. Error Boundary یک مدیریتکننده خطای ساده اما مؤثر برای لایه رابط کاربری است.
خطای کشنده یک استثنای مدیریتنشده است که باعث کرش برنامه میشود. خطای غیرکشنده یک استثنا است که شما گرفته و مدیریت کردهاید، اما نشاندهنده مشکلی در کد است. خطاهای غیرکشنده از طریق Crashlytics/Sentry ثبت میشوند و به یافتن باگها قبل از کشنده شدن کمک میکنند. هر دو خطای کشنده و غیرکشنده به مدیریت صحیح خطا در توسعه موبایل نیاز دارند.
سوالات متداول
try-catch یک مکانیسم زبان برای استثناها است. Result یک نوع wrapper است که مدیریت خطا را در زمان کامپایل اجباری میکند. در IT Sectr، ما Result را برای منطق کسبوکار و try-catch را برای کار با سیستمهای خارجی ترجیح میدهیم. هر دو رویکرد بخشی از مدیریت کلی خطا در Kotlin هستند.
Error Boundary یک کامپوننت React است که خطاهای JavaScript را در درخت کامپوننتهای فرزند میگیرد و به جای کرش کل برنامه، یک رابط کاربری جایگزین نشان میدهد. خطاهای کد ناهمگام یا رندر سمت سرور را نمیگیرد. Error Boundary یک عنصر مهم مدیریت خطا در برنامههای موبایل در React Native است.
Crashlytics (Firebase) بهترین انتخاب برای شروع است: رایگان، یکپارچهسازی ساده، گروهبندی خودکار کرشها. Sentry برای پروژههایی است که نیاز به ردیابی جزئیات خطا و نظارت بر عملکرد دارند. انتخاب ابزار مدیریت خطا به بودجه و الزامات نظارت بستگی دارد.
خطای کشنده یک کرش برنامه است (استثنای گرفتهنشده). خطای غیرکشنده یک استثنا است که شما گرفته و مدیریت کردهاید، اما نشاندهنده مشکلی در کد است. خطاهای غیرکشنده به طور جداگانه ثبت میشوند و به یافتن باگها قبل از کشنده شدن کمک میکنند. مدیریت خطا در یک برنامه موبایل باید شامل نظارت بر هر دو نوع باشد.
guard let برای خروج زودهنگام از تابع در صورت نبود مقدار استفاده میشود — این کار کد را خطیتر و خواناتر میکند. if-let زمانی مناسب است که optional درون یک بلوک نیاز باشد و خروج از تابع لازم نباشد. guard let برای اعتبارسنجی پارامترهای ورودی ترجیح داده میشود و بخشی از مدیریت خطا در iOS است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.