Koje načine za obradu grešaka u korutinama poznajete?
sobes.tech АИ
Одговор од АИ
-
Korišćenje
try...catchblokova. Standardan način za obradu izuzetaka. Radi unutar korutine.// Korišćenje try-catch suspend fun fetchData(): String { return try { // Operacija koja može da baci izuzetak throw Exception("Greška pri učitavanju podataka") "Podaci uspešno učitani" } catch (e: Exception) { "Greška: ${e.message}" } }try...catchnije pogodan za obradu neuhvaćenih izuzetaka, bačenih od strane podkora, pokrenutih u drugomCoroutineScope. -
CoroutineExceptionHandler. Hvata neobrađene izuzetke, bačene od strane korutina koje su pokrenute u ovomCoroutineScopeili njegovim podkora.// CoroutineExceptionHandler val handler = CoroutineExceptionHandler { _, exception -> println("Uhvaćen izuzetak: $exception") } // Korišćenje CoroutineExceptionHandler GlobalScope.launch(handler) { // Korutina koja može da baci izuzetak throw Exception("Greška u korutini") }CoroutineExceptionHandlerse aktivira samo za izuzetke koji nisu obrađeni mehanizmom strukturirane konkurencije. -
SupervisorJobisupervisorScope. Za razliku od običnogJob, kada podkora sa greškom dovodi do otkazivanja roditeljskogJob,SupervisorJobne otkazuje roditeljskiJobpri grešci podkore.supervisorScopekreiraCoroutineScopesaSupervisorJob.// Korišćenje supervisorScope suspend fun loadMultipleData() = supervisorScope { val data1 = async { // Može da baci izuzetak throw Exception("Greška u podacima 1") "Podaci 1" } val data2 = async { "Podaci 2" } // Može da obradi izuzetak za konkretnu async try { println("Rezultat 1: ${data1.await()}") } catch (e: Exception) { println("Greška pri učitavanju podataka 1: ${e.message}") } println("Rezultat 2: ${data2.await()}") }Koristi se za nezavisne podzadatke, gde greška jednog ne bi trebalo da utiče na ostale. Ne zamenjuje
try...catchiliCoroutineExceptionHandler, već menja ponašanje širenja izuzetaka. -
Širenje izuzetaka u strukturiranoj konkurenciji. Po default-u, izuzetak u podkori otkazuje roditeljsku korutinu i sve njene srodnike.
// Primer širenja izuzetka runBlocking { val job = launch { launch { // Podkora 1 delay(100) throw Exception("Greška u podkori 1") } launch { // Podkora 2 delay(200) println("Podkora 2 završila") } } try { job.join() } catch (e: Exception) { println("Uhvaćen izuzetak u roditelju: $e") } }Ovo je osnovno ponašanje strukturirane konkurencije, koje pomaže da se izbegnu curenja resursa i stanja.
-
Korišćenje
asyncsaawait(). Izuzeci, bačeni uasync, ne se automatski šire. Oni se čuvaju unutarDeferredi bacaju se samo pri pozivuawait().// Obrada izuzetaka sa async/await suspend fun safeAsyncCall() = coroutineScope { val deferred = async { throw Exception("Greška u async") "Rezultat async" } try { val result = deferred.await() println("Rezultat: $result") } catch (e: Exception) { println("Uhvaćen izuzetak iz async: ${e.message}") } }Ovo omogućava selektivnu obradu grešaka za svaku asinhronu zadatak.
| Način | Namenjen za | Obradjuje neuhvaćene? | Menja širenje? |
|---|---|---|---|
try...catch |
Obrada izuzetaka unutar trenutne korutine | Ne | Ne |
CoroutineExceptionHandler |
Hvata neobrađene izuzetke u Scope | Da | Ne |
SupervisorJob/Scope |
Promena ponašanja širenja izuzetaka | Ne | Da |
| Struktuisana konkurencija | Automatsko otkazivanje pri grešci | Da | Da |
async + await() |
Odloženo širenje izuzetka | Ne | Da (do await) |