Šta se dešava sa korutinom kada dođe do izuzetka?
sobes.tech АИ
Одговор од АИ
Када се појави изузетак унутар корутине, зависност од типа изузетка (и подешавања диспетчера/контекста) одређује како ће бити обрађен.
-
Неконтролисани изузетак: Ако изузетак није ухваћен унутар корутине, он се пропагира нагоре кроз хијерархију корутина до најближег родитељског
Job(илиCoroutineScope). Понашање зависи од типаJob:Job: По подразумевану, ако дође до изузетка у дечијој корути, родитељскиJobсе отказује, што доводи до отказивања свих осталих дечијих корутина. Изузетак се преноси горе.SupervisorJob: РодитељскиSupervisorJobсе не отказује када дође до изузетка у дечијој корути. Само сама корутина у којој је дошло до изузетка се отказује. Ово је корисно када је потребно да отказивање једне дечије задаће не утиче на друге.- Коренски
CoroutineScope: Ако изузетак достигне коренскиCoroutineScope(нпр.GlobalScopeили scope креиран помоћуCoroutineScopeбезJob), он се преноси у глобални обработљач изузетакаCoroutineExceptionHandler. По подразумевану, ако нема регистрованог обработљача, изузетак се логова уSystem.err.
-
Хваћени изузетак: Ако је изузетак ухваћен помоћу
try-catchблока унутар корутине, он се обрађује локално, и корутина наставља са извршавањем након блокаcatch, ако је то могуће. Изузетак се не преноси горе. -
Изузетци везани за отказивање (нпр.
CancellationException): Ови изузетци су посебни. Користе се за механизам отказивања корутина и обично се игноришу од стране већине обработљача изузетака по подразумеваној. Они не доводе до фаталног пада родитељскогJobпо подразумеваној. -
Изузетци у
async: Корутине покренуте помоћуasyncстављају изузетак у својDeferred. Изузетак се преноси само при позиву.await()на томDeferred. До тада је изузетак "скривен".
import kotlinx.coroutines.*
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob())
scope.launch {
try {
println("Корутинa 1 започела")
delay(100)
throw RuntimeException("Нешто је пошло по злу у Корутинa 1")
} catch (e: Exception) {
println("Хваћен изузетак у Корутинa 1: ${e.message}")
}
}
scope.launch {
println("Корутинa 2 започела")
delay(500)
println("Корутинa 2 завршена")
}
delay(1000) // Чекамо да видимо излаз
scope.cancel() // Отказујемо scope
}
У овом примеру, изузетак у Корутинa 1 је хваћен, и Корутинa 2 наставља са извршавањем, јер је коришћен SupervisorJob. Ако би био коришћен обичан Job, изузетак у Корутинa 1 би довео до отказивања Корутинa 2.