Обробка помилок — фундаментальний навик мобільного розробника. За даними 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. Якщо помилка не оброблена, вона прокидається вище по стеку (Error Propagation). Для ефективної обробки помилок в iOS використовуйте do-catch як основний механізм.
Throw оголошується в сигнатурі функції: func fetchData() throws -> Data. Це означає, що код, який викликає, зобов'язаний обробити помилку через try, try? або try!. try? перетворює помилку в nil, try! викликає crash при помилці (використовуйте тільки якщо впевнені в успіху). Обробка помилок через throw — обов'язкова практика в Swift.
Guard let — конструкція для раннього виходу з функції, якщо значення дорівнює nil. На відміну від if-let, guard let вимагає exit (return, throw, break) в else-гілці. Це робить код більш пласким і читабельним — без вкладених if-блоків. Якщо optional не може бути nil — використовуйте force unwrap (!), тільки коли абсолютно впевнені. В мобільному додатку guard let допомагає уникнути крашів при обробці опціональних значень.
Optional Chaining (user?.address?.city) та nil-coalescing (??) — синтаксичний цукор для роботи з optional без розгортання. В IT Sectr ми використовуємо guard let для валідації вхідних параметрів API і примушуємо команду уникати force unwrap без явного коментаря. Обробник помилок на кожному рівні захищає від непередбачених збоїв.
Kotlin — основна мова для Android-розробки. Він успадковує try-catch з Java, але додає більш безпечні альтернативи: elvis-оператор, require, check та sealed class. Обробка помилок в Kotlin будується на комбінації цих механізмів. На відміну від Swift, Kotlin дозволяє не обробляти checked exceptions (всі винятки unchecked). Для обробки помилок в мобільних додатках на Android використовуйте sealed class як основний патерн.
Try-catch в Kotlin працює як expression — він повертає значення. val result = try { fetchData() } catch (e: Exception) { fallbackValue }. Це скорочує код. Elvis-оператор (?:) — аналог nil-coalescing для nullable-типів: val name = user?.name ?: "Guest". Для обробки помилок в мобільних додатках try-catch як expression — найбільш лаконічний підхід.
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 клас NetworkResult моделює два стани: успіх з даними та помилка з повідомленням. Функція fetchUser повертає результат в будь-якому випадку, код, що викликає, обробляє обидві гілки через when. Це виключає стан, коли помилка не оброблена. Обробник помилок через sealed class — стандарт для Android-розробки в IT Sectr.
Result — вбудований тип Kotlin для представлення результату операції, яка може завершитися помилкою. Він примушує обробляти success та failure через fold, getOrThrow або map. Result корисний в асинхронних ланцюжках (coroutines). Обробка помилок за допомогою Result — стандарт для мобільної розробки на Kotlin.
Either — функціональний тип з бібліотеки Arrow, який дозволяє повернути значення одного з двох типів (Left — помилка, Right — успіх). На відміну від Result, Either може містити будь-який user-defined тип помилки. Для простих проектів достатньо вбудованого Result, для складних — Either з Arrow. Вибір інструменту для обробки помилок залежить від складності проекту.
Error Propagation — механізм, при якому помилка прокидається вгору по стеку викликів, поки не буде оброблена. В Kotlin це відбувається за замовчуванням (unchecked exceptions). В 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 |
| Checked exceptions | Так (throws) | Ні (всі unchecked) |
| Non-fatal | os_log, Crashlytics | Timber, Crashlytics |
Таблиця показує ключові відмінності. iOS вимагає явної декларації помилок (throws), що робить код безпечнішим, але більш багатослівним. Android покладається на дисципліну розробника. В IT Sectr ми використовуємо sealed class для Android та throws для iOS — це best practice обох платформ для обробки помилок в мобільному додатку.
Crash reporting — система збору та аналізу крашів додатку. Crash reporting — невід'ємна частина обробки помилок в продакшені. Без неї ви дізнаєтеся про проблеми від користувачів, що неприйнятно для продакшену. Два основні інструменти: Firebase Crashlytics (безкоштовно) та Sentry (безкоштовно для базового використання). Для обробки помилок в мобільних додатках обов'язково впроваджуйте crash reporting з першого релізу.
Crashlytics — частина Firebase. Автоматично збирає краші, групує їх по стеку викликів і показує кількість порушених користувачів. Підтримує логування non-fatal помилок через recordException(). Інтеграція: додайте SDK в build.gradle (Android) або Podfile (iOS). Crashlytics — найкращий безкоштовний інструмент для обробки помилок на старті проекту.
Sentry — крос-платформна система моніторингу помилок. На відміну від Crashlytics, Sentry дає детальну трасування (breadcrumbs), performance monitoring та підтримку React Native. Дозволяє переглядати стан додатку в момент помилки. IT Sectr рекомендує Sentry для проектів, де потрібен повний контроль над обробкою помилок в мобільній розробці.
Error Boundary — React-компонент, який ловить JavaScript-помилки в дочірньому дереві та відображає fallback UI, запобігаючи повному падінню додатку. Error Boundary — ключовий компонент для обробки помилок в React Native. Використовуйте error boundaries для критичних екранів та навігації. Обробка помилок в мобільних додатках на React Native вимагає правильного налаштування Error Boundary на верхньому рівні.
Error Boundary створюється через componentDidCatch(error, errorInfo) або static getDerivedStateFromError(error). Він не ловить помилки в асинхронному коді (setTimeout, requestAnimationFrame), серверному рендерингу або власні помилки (Native Modules). Для логування використовуйте crash reporting SDK всередині componentDidCatch. Error Boundary — простий, але ефективний обробник помилок для UI-шару.
Fatal error — це необроблений виняток, який призводить до крашу додатку. Non-fatal error — це виняток, який ви піймали та обробили, але він вказує на проблему в коді. Non-fatal помилки логуються через Crashlytics/Sentry та допомагають знайти баги до того, як вони стануть фатальними. І фатальні, і нефатальні помилки вимагають грамотної обробки помилок в мобільній розробці.
Часто задавані питання
try-catch — це механізм мови для винятків. Result — це тип-обгортка, який примушує обробляти помилку на етапі компіляції. В IT Sectr ми віддаємо перевагу Result для бізнес-логіки та try-catch для роботи із зовнішніми системами. Обидва підходи — частина загальної обробки помилок в Kotlin.
Error Boundary — це React-компонент, який відловлює JavaScript-помилки в дочірньому дереві компонентів і показує запасний UI замість падіння всього додатку. Він не ловить помилки в асинхронному коді та серверному рендерингу. Error Boundary — важливий елемент обробки помилок в мобільних додатках на React Native.
Crashlytics (Firebase) — найкращий вибір для початку: безкоштовно, проста інтеграція, автоматичне групування крашів. Sentry — для проектів, де потрібна детальна трасування помилок та моніторинг продуктивності. Вибір інструменту для обробки помилок залежить від бюджету та вимог до моніторингу.
Fatal error — це краш додатку (uncaught exception). Non-fatal error — це виняток, який ви піймали та обробили, але він говорить про проблему в коді. Non-fatal помилки логуються окремо і допомагають знаходити баги до того, як вони стануть фатальними. Обробка помилок в мобільному додатку повинна включати моніторинг обох типів.
guard let використовується для раннього виходу з функції при відсутності значення — це робить код більш лінійним та читабельним. if-let підходить, коли optional потрібен всередині блоку і не потрібен вихід з функції. guard let кращий для валідації вхідних параметрів і є частиною обробки помилок в iOS.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.