Try-Catch: podstata, konstrukce zachycení výjimek a jak funguje v mobilním vývoji

Autor: IT Sectr Publikováno: 2026-05-25 Doba čtení: 9 min

Try-Catch — konstrukce zachycení výjimek, která umožňuje provádět potenciálně nebezpečný kód v chráněném bloku a správně zpracovávat chyby bez náhlého ukončení programu. Blok try obsahuje kód, který může vyhodit výjimku, catch ji zachytí a provede logiku obnovy. Podle Apple Swift Documentation (2026) se blok finally provádí bez ohledu na to, zda byla výjimka vyhozena či nikoli, a zaručuje uvolnění prostředků.

Hlavní Body

  • Try-Catch — konstrukce pro zachycení výjimek, která zabraňuje náhlému ukončení programu při chybách
  • Blok try obsahuje kód, který může vyhodit výjimku — provádění se přeruší při první chybě
  • Blok catch zachytí výjimku zadaného typu a provede logiku zpracování nebo obnovy
  • Blok finally se zaručeně provádí po try/catch pro uvolnění prostředků, např. zavření souborů
  • Vnořené try-catch umožňují zpracovávat chyby na různých úrovních abstrakce uvnitř jedné funkce

Co je Try-Catch?

Try-Catch — základní konstrukce strukturovaného zpracování výjimek, přítomná ve většině moderních programovacích jazyků. Skládá se ze tří bloků: try (pokus o provedení nebezpečného kódu), catch (zachycení a zpracování výjimky) a volitelného finally (finalizace). Myšlenkou konstrukce je oddělení logiky obchodních operací od logiky zpracování chyb, což činí kód čitelnějším a předvídatelnějším.

Koncepce byla poprvé implementována v jazyce C++ jako try/catch, poté převzata jazyky Java, C#, Swift, Kotlin, Dart, Python, JavaScript a dalšími. Každý jazyk přidává své vlastní rysy: ve Swift musí být blok catch vyčerpávající, v Kotlin může být try-catch výrazem (expression), v Dart je finally povinný pro prostředky proudu. Navzdory rozdílům je základní princip stejný: chyba je zpracována co nejblíže místu vzniku, nikoli globálně.

Použití Try-Catch je obzvláště důležité v mobilním vývoji, kde vnější faktory — ztráta sítě, nesprávná odpověď serveru, nedostatek paměti — neustále vznikají. Správné zpracování výjimek zabraňuje pádům aplikace a zajišťuje správné UX: uživatel obdrží chybovou zprávu místo náhlého zavření aplikace. Podle Google Android Kotlin Style Guide (2026) by každá funkce, která může vyhodit výjimku, měla buď ji zpracovat pomocí try-catch, nebo deklarovat throws v signatuře.

Jak funguje Try-Catch

Mechanismus provádění try-catch je založen na odvíjení zásobníku (stack unwinding). Když je uvnitř bloku try vyhozena výjimka pomocí operátoru throw (nebo v důsledku systémové chyby), normální tok provádění je okamžitě přerušen. Provádění se přesune na vyšší úroveň zásobníku volání při hledání vhodného bloku catch. Moderní jazyky hledají catch s typem odpovídajícím typu vyhozené výjimky pomocí mechanismu porovnávání typů (type matching).

Pokud je nalezen odpovídající catch, provede se jeho tělo, poté provádění pokračuje za celou konstrukcí try-catch-finally. Pokud catch není nalezen, výjimka stoupá dále v zásobníku a může být zpracována na vyšší úrovni — až po globální handler, který v mobilní aplikaci zobrazí uživateli dialog s chybou. Pokud výjimka není zpracována nikde, aplikace spadne. Právě proto je správné zpracování všech možných typů výjimek kritické pro stabilitu aplikace.

Syntaxe základní konstrukce

kotlin
fun readUserData(): User {
    return try {
        val response = api.fetchUser()
        parseUser(response)
    } catch (e: IOException) {
        logError("Chyba sítě", e)
        throw AppException("Nepodařilo se načíst data")
    } catch (e: JsonParseException) {
        logError("Chyba parsování", e)
        return User.default()
    } finally {
        closeLoadingIndicator()
    }
}

Kód se nejprve pokusí provést dotaz API a zpracovat odpověď. Pokud dojde k IOException (problém se sítí), výjimka je zalogována a předána dále jako AppException. Pokud JsonParseException — je vrácen výchozí uživatel. Blok finally zaručeně skryje indikátor načítání a zabraňuje úniku komponent UI na obrazovce.

Try-Catch ve Swift

Ve Swift je zpracování chyb implementováno prostřednictvím protokolu Error (dříve ErrorType). Jakýkoli typ kompatibilní s Error může být vyhozen pomocí operátoru throw. Funkce, která může vyhodit chybu, je označena klíčovým slovem throws v signatuře. Volání takové funkce vyžaduje předponu try (pro explicitní try-catch), try? (volitelný výsledek) nebo try! (vynucené provedení bez zpracování chyby).

swift
enum NetworkError: Error {
    case noConnection
    case serverError(code: Int)
    case timeout
}

func fetchUser(id: Int) throws -> User {
    guard isConnected() else {
        throw NetworkError.noConnection
    }
    let data = try performRequest(path: "/users/\(id)")
    return try decodeUser(from: data)
}

do {
    let user = try fetchUser(id: 42)
    updateUI(user)
} catch NetworkError.noConnection {
    showOfflineAlert()
} catch let error as NetworkError {
    showError("Síť " + error.localizedDescription)
} catch {
    showGenericError()
}

Enum NetworkError implementuje protokol Error a definuje tři případy: noConnection, serverError s kódem a timeout. Funkce fetchUser je označena throws: nejprve zkontroluje připojení, poté provede dotaz a zpracování. V bloku do-catch tři catch zpracovávají různé scénáře: specifický případ noConnection, obecný typ NetworkError a všechny ostatní chyby. To umožňuje zobrazovat uživateli různé zprávy v závislosti na typu problému.

Try-Catch v Kotlin

Kotlin zdědil try-catch-finally od Javy, ale přidal důležitý rozdíl: v Kotlin je try-catch výraz (expression), nikoli příkaz (statement). To znamená, že výsledek bloku try nebo bloku catch lze přiřadit proměnné. Poslední výraz v bloku try se stává výsledkem při úspěchu, poslední výraz v catch — při chybě. Pokud chyba není zpracována žádným catchem, výjimka je předána výše v zásobníku.

kotlin
sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Throwable) : Result<Nothing>()
}

fun loadData(): Result<List<Item>> {
    return try {
        val response = api.getItems()
        Result.Success(response.toList())
    } catch (e: HttpException) {
        Log.e("HTTP ", e)
        Result.Error(e)
    } catch (e: IOException) {
        Log.e("Síť ", e)
        Result.Error(e)
    }
}

V příkladu sealed class Result obaluje úspěšnou odpověď nebo chybu. Funkce loadData používá try-catch jako výraz: při úspěchu vrací Result.Success, při výjimce HttpException nebo IOException — Result.Error s logováním. Tento přístup umožňuje volající straně zpracovávat chyby bez výjimek — pomocí when-výrazu podle typu Result. To je obzvláště výhodné v Jetpack Compose pro zobrazení různých stavů UI (Loading, Success, Error) prostřednictvím StateFlow a collectAsState.

Try-Catch v Dart a Flutter

Dart podporuje try-catch-finally se syntaxí podobnou Javě, ale s přidáním klauzule on pro filtrování podle typu výjimky bez uvedení proměnné. To je výhodné, když samotná výjimka není potřeba — důležitý je pouze fakt jejího typu. Dart také podporuje blok catch se dvěma parametry: objekt výjimky a StackTrace, což je užitečné pro logování celého řetězce volání.

dart
import 'dart:io';
import 'dart:convert';

class UserRepository {
    Future<User> fetchUser(String id) async {
        try {
            final client = HttpClient();
            final request = await client.getUrl(
                Uri.parse('https://api.example.com/users/$id')
            );
            final response = await request.close();
            final body = await response.transform(utf8.decoder).join();
            return User.fromJson(json.decode(body));
        } on SocketException catch (e, stackTrace) {
            log("No internet", e, stackTrace);
            throw AppException("Connection failed");
        } on FormatException {
            throw AppException("Invalid response format");
        } finally {
            client.close();
        }
    }
}

SocketException je zachyceno s objektem a StackTrace pro podrobné logování, poté předáno jako AppException. FormatException je zachyceno bez proměnné — stačí vědět, že formát odpovědi je nesprávný. Blok finally zaručeně zavře HttpClient a zabraňuje úniku socketů. Ve Flutter je tento přístup obzvláště důležitý pro testování Widget, kde neošetřené výjimky v State.initState vedou k pádu celé testovací relace.

Typické chyby při používání Try-Catch

Dokonce i zkušení vývojáři dělají chyby při práci s try-catch, které vedou k únikům paměti, skrytým chybám nebo nevhodnému chování aplikace. Podívejme se na pět nejčastějších problémů v mobilním vývoji.

Prázdný blok catch

Prázdný catch — jedna z nejhorších praktik. Výjimka je spolknuta, aplikace pokračuje v činnosti v nesprávném stavu a vývojář se o problému nedozví. Vždy alespoň zalogujte výjimku. V Kotlin použijte catch(e: Exception) { Log.e(...) }, ve Swift — catch { print($0) }. V Dart by minimálně přijatelný catch měl volat debugPrint nebo zapisovat do Crashlytics.

Příliš široký catch

Zachycování všech výjimek pomocí catch (Exception e) bez rozlišení podle typů skrývá neočekávané chyby — NullPointerException, OutOfMemoryError, StackOverflowError. Chytejte pouze ty typy, které očekáváte a můžete zpracovat. Pro zbytek povolte propagaci výše. V mobilním vývoji dávají specifické catch pro IOException, TimeoutException, AuthException smysluplnější zprávy uživateli.

Ignorování finally

Prostředky — soubory, sockety, kurzory DB, animace — by měly být uvolňovány v finally nebo v bloku use (AutoCloseable). Vývojáři často zapomínají zavírat prostředky při výjimce, což vede k únikům. V Kotlin použijte .use { } pro prostředky Closeable, ve Swift — defer { }, v Dart — await using z balíčku async. Blok finally zaručuje uvolnění i při vyhození výjimky uvnitř catch.

Výjimky ve vláknech a korutinách

V asynchronním kódu try-catch nezachycuje výjimky z jiných vláken. V Kotlin Coroutines použijte CoroutineExceptionHandler nebo SupervisorJob. Ve Swift async/await — do-catch uvnitř Task. Ve Flutter — runZonedGuarded pro globální zachycení. Ignorování tohoto pravidla je příčinou obtížně reprodukovatelných pádů v produkci.

Blokování UI při výjimce

Zpracování výjimky by nemělo blokovat uživatelské rozhraní na neurčitou dobu. Ukažte uživateli konkrétní zprávu a dejte možnost operaci zopakovat. Snackbar s tlačítkem Retry v Kotlin/Compose, UIAlertController s action ve Swift, SnackBar s action ve Flutter — minimálně dostačující UX pro chyby sítě nebo serveru. Vyhněte se obecným dialogům „Došlo k chybě" bez možnosti obnovy.

Často kladené otázky

Čím se liší try-catch od Result Type?

Try-catch používá pro zpracování chyb výjimky a odvíjení zásobníku, což může být při velkém počtu chyb výkonnostně nákladné. Result Type je typ-kontejner (Success nebo Failure), který je zpracováván pomocí pattern matching bez odvíjení zásobníku, což je efektivnější pro očekávané chyby.

Je třeba používat finally v každém try-catch?

Finally je povinný, pokud blok try otevírá prostředky (soubory, sockety, kurzory), které je třeba zavřít. Pokud se prostředky neotevírají, finally není vyžadován. V moderních jazycích použijte AutoCloseable/use/defer pro automatické zavírání prostředků bez finally. Blok use v Kotlin a Swift nahrazuje finally pro objekty Closeable.

Může být try-catch pomalý?

V normálním toku (bez výjimky) try-catch prakticky neovlivňuje výkon — JVM a kompilátor Swift tento případ optimalizují. Ale při vyhození výjimky dochází k odvíjení zásobníku, což může trvat 10–100 µs v závislosti na hloubce zásobníku. Nepoužívejte výjimky pro řízení toku provádění — je to antivzor.

Jak zpracovávat chyby v Kotlin Coroutines?

V korutinách použijte try-catch uvnitř coroutineScope nebo CoroutineExceptionHandler pro globální zachycení. SupervisorJob zabraňuje zrušení rodičovské korutiny při chybě v podřízené korutině. Pro launch použijte CoroutineExceptionHandler, pro async — try-catch kolem await().

Co je lepší: vícenásobné catch nebo jeden catch s if-else?

Vícenásobné catch jsou preferovanější: kód se čte lineárně, každý blok zpracovává jeden typ výjimky. Jeden catch s if-else je obtížnější udržovat, snadno lze přehlédnout nový typ výjimky. Ve Swift jsou vícenásobné catch povinné pro vyčerpávající zpracování enum Error, v Kotlin neexistují omezení, ale nejlepší praxí je samostatný catch na typ.

Shrnutí

  • Try-Catch — konstrukce zachycení výjimek s bloky try, catch a volitelným finally pro zaručené uvolnění prostředků
  • Mechanismus fungování — odvíjení zásobníku při vyhození výjimky s hledáním vhodného catch podle typu chyby
  • Ve Swift se používá do-catch s enum Error, try? pro volitelný výsledek a try! pro zaručený úspěch
  • V Kotlin je try-catch výraz, jehož výsledek lze přiřadit proměnné, výhodně v páru se sealed class Result
  • V Dart podporuje klauzuli on pro filtrování podle typu bez proměnné a finally pro zavření HttpClient
  • Typické chyby: prázdný catch, příliš široké zachycování, ignorování finally a chybějící zpracování v korutinách
  • Používejte try-catch pro neočekávané chyby, Result Type — pro očekávané scénáře s možným selháním

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í.

Prodiskutovat projekt

Přečtěte si také