Non-Fatal Error — je chyba, která nevede k ukončení aplikace a umožňuje pokračovat v provádění programu. Na rozdíl od fatal error mohou být nefatální chyby zachyceny, zpracovány a zalogovány bez ztráty uživatelské relace. Podle údajů Firebase Crashlytics Documentation, 2024 je přibližně 70 % všech zaznamenaných chyb v produkčních aplikacích nefatálních, ale jejich ignorování vede k hromadění technického dluhu a postupnému zhoršování uživatelského zážitku. Správné zpracování non-fatal chyb je jednou z klíčových dovedností mobilního vývojáře.
Hlavní body
Non-Fatal Error — je výjimka nebo chybový stav, který nezpůsobuje ukončení procesu. Aplikace nadále funguje, ale může být v nesprávném stavu: data se nenačetla, požadavek se neodeslal, prvek rozhraní se nezobrazil. Uživatel buď chybu nezaznamená, nebo vidí zprávu a pokračuje v používání aplikace.
Nefatální chyba vždy ponechává programu cestu k obnovení. Zpracovatel chyb může nabídnout alternativní data, zopakovat operaci nebo zobrazit zástupný prvek rozhraní. Hlavním úkolem je zabránit crashi a udržet uživatelský zážitek na přijatelné úrovni. Vývojář musí výslovně předvídat scénář obnovení v každém bloku catch.
Podle údajů Instabug 2024 65 % uživatelů odstraňuje aplikaci po dvou neúspěšných interakcích. Non-fatal chyby ponechané bez povšimnutí se hromadí a snižují celkovou kvalitu provozu. Systematické logování a opravování nefatálních chyb je přímou cestou ke zvýšení retence a zlepšení uživatelských hodnocení v obchodech s aplikacemi.
Síťové chyby — nejčastější typ non-fatal chyb v mobilních aplikacích. Časový limit připojení, ztráta sítě, nesprávný stavový kód serveru — všechny tyto situace jsou zachyceny a zpracovány bez crashi. Uživateli se zobrazí zpráva o nedostupnosti služby s návrhem opakování. Pro síťové chyby je typický vzor retry s exponenciálním zpožděním.
Nesprávný formát odpovědi serveru, chybějící povinné pole, nesprávný typ dat — chyby parsování jsou nefatální, pokud aplikace správně zpracovává nesprávná data. Typickým přístupem je použití výchozích záložních hodnot a logování chyby parsování s kontextem požadavku pro pozdější analýzu na serveru.
Problémy s načítáním obrázků, nesprávná písma, chyby v rozložení — všechny nejsou fatální, ale zhoršují dojem uživatele. Zástupné obrázky a fallback hodnoty umožňují vyhnout se prázdným obrazovkám a činí chyby méně viditelnými. V React Native se pro UI chyby používá Error Boundary se zobrazením záložní komponenty.
Chyby ve výpočtech, nesoulad stavů, nesprávné přechody mezi obrazovkami — logické chyby často nevedou k crashi, ale vedou k nesprávnému chování aplikace. Je obtížnější je odhalit bez systematického logování a monitorování, protože nevytvářejí crash report a zůstávají nepovšimnuty až do stížnosti uživatele.
Non-Fatal Error se liší od fatal tím, že ponechává programu možnost pokračovat v práci. Fatal error — je stav, ze kterého se aplikace nemůže zotavit: dereference null ukazatele, přetečení zásobníku, nedostatek paměti. Non-fatal chybu lze zachytit, zpracovat a pokračovat v provádění, zatímco fatal error vyžaduje restart aplikace.
| Vlastnost | Non-Fatal Error | Fatal Error |
|---|---|---|
| Ukončení aplikace | Ne | Ano |
| Možnost obnovení | Ano, pomocí bloku catch | Ne |
| Logování | Z kódu přes recordException | Pouze crash reporterem |
| Dopad na UX | Dočasné nepohodlí | Úplná ztráta relace |
| Příklad | Network timeout, parse error | NullPointerException, OOM |
Hranice mezi non-fatal a fatal může záviset na implementaci. Časový limit sítě je v jedné aplikaci zpracováván jako non-fatal (opakování požadavku po 1–2 sekundách), v jiné může být fatální (crash při absenci zpracovatele). Kvalitní zpracování chyb přeměňuje potenciálně fatální situace na nefatální, čímž zvyšuje stabilitu aplikace. Navrhování systému zpracování chyb je jedním z klíčových architektonických úkolů při vývoji mobilní aplikace s vysokými požadavky na spolehlivost. Vestavěný monitorovací systém umožňuje týmu rychle odhalovat a odstraňovat nefatální chyby dříve, než ovlivní významný počet uživatelů.
Firebase Crashlytics — hlavní nástroj pro logování nefatálních chyb v mobilních aplikacích. Metoda recordException umožňuje zaznamenat non-fatal výjimku s úplným stack trace a kontextem provádění, aniž by došlo k přerušení činnosti aplikace. Na rozdíl od crash reportů lze recordException volat na libovolném místě kódu pro logování zachycených výjimek.
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: používáme záložní data
Crashlytics.recordException(e)
showFallbackContent()
}
}
// Logování s uživatelskými klíči
Crashlytics.setCustomKey("screen", "Profile")
Crashlytics.setCustomKey("api_version", "v3")
Sentry — alternativa k Crashlytics s podrobnější diagnostikou non-fatal chyb. Sentry SDK poskytuje metodu captureException, která odesílá podrobnosti výjimky na server. Klíčovou výhodou Sentry je seskupování podobných non-fatal chyb do jednoho issue, analýza frekvence opakování a kontext provádění ve formě breadcrumbs — posloupnosti akcí uživatele před chybou.
Ne všechny non-fatal chyby je třeba logovat. Očekávané stavy — výpadek sítě při absenci připojení — lze logovat selektivně. Neočekávané chyby — NullPointerException ve zpracovaném kódu, nesprávný formát dat, logic error — by měly být logovány vždy. Každý tým určuje práh významnosti: v průměru 10 až 20 unikátních non-fatal chyb na 1000 uživatelů denně je považováno za normu. Důležité je nastavit alerty na prudký nárůst počtu non-fatal chyb — to může naznačovat problémy s novou verzí API nebo regresi po vydání.
Základním mechanismem zpracování je try-catch, který zachycuje výjimku a provádí kód obnovení. Pro síťové operace je typickým vzorem opakování požadavku s exponenciálním zpožděním (retry with backoff). Pro chyby parsování — použití výchozích záložních hodnot a logování kontextu pro pozdější analýzu na straně serveru.
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)
}
Typy Result — alternativní přístup bez výjimek. Funkce vrací sealed class Result s variantami Success a Failure. Volající kód zpracovává obě varianty explicitně, což eliminuje neošetřené chyby. Typy Result jsou populární v Kotlin (Result
Pro každý typ non-fatal chyby je třeba předvídat strategii obnovení: načtení dat z cache při síťové chybě, použití výchozích hodnot při chybě parsování, opětovná inicializace komponenty při UI chybě. Dobrou praxí je zobrazení toastu nebo snackbaru se zprávou o chybě uživateli, ale ne úplné blokování interakce s aplikací. Důležité je rozlišovat obnovitelné (recoverable) a neobnovitelné chyby — pro druhé bude strategie obnovení jiná, například návrh na restartování obrazovky nebo vymazání dat. Ukládání předchozího úspěšného stavu do cache se často ukazuje jako nejjednodušší a nejefektivnější způsob zpracování non-fatal chyb na mobilních platformách.
Často kladené otázky
Warning — je varování kompilátoru nebo statického analyzátoru o potenciálním problému v kódu. Non-fatal error — je runtime výjimka, která již nastala, ale nevedla k crashi. Warning lze odstranit před kompilací, non-fatal error — zpracovat během provádění pomocí bloku catch.
Ne, nadměrné logování zahlcuje monitorování. Vyplatí se logovat neočekávané chyby v produkci a ignorovat očekávané stavy: výpadek sítě při absenci připojení se loguje selektivně, zatímco NullPointerException ve zpracovaném kódu — vždy. Každý tým určuje práh významnosti na základě kontextu aplikace.
Ve SwiftUI se používá ObservableObject s @Published polem errorState pro sledování chybového stavu. View se přihlásí ke změnám a zobrazí alternativní obsah. Před iOS 17 se používal Combine se zpracovateli, od iOS 17 — SwiftData a @Observable makra pro reaktivní aktualizaci UI.
Ano, pokud chyba vyvolá řetězovou reakci. Příklad: nefatální selhání načítání obrázku může vést k nesprávnému stavu UI, který pak způsobí crash při pokusu o zobrazení. Kvalitní zpracování non-fatal chyb na každé úrovni zabraňuje jejich eskalaci na fatální úroveň.
V iOS jsou non-fatal chyby zpracovávány pomocí do-catch s throw, v Androidu — pomocí try-catch s výjimkami. iOS používá NSError s doménami a kódy chyb, Android — Java/Kotlin výjimky. Crashlytics funguje stejně na obou platformách přes recordException a poskytuje jednotné rozhraní pro monitorování.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také