Que se passe-t-il avec une coroutine lorsqu'une exception se produit?
sobes.tech IA
Réponse de l'IA
Lorsqu'une exception se produit à l'intérieur d'une coroutine, la dépendance au type d'exception (et aux paramètres du dispatcher/contexte) détermine comment elle sera traitée.
-
Exception non gérée : Si l'exception n'est pas capturée à l'intérieur de la coroutine, elle se propage vers le haut dans la hiérarchie des coroutines jusqu'au
JobouCoroutineScopele plus proche. Le comportement dépend du type deJob:Job: Par défaut, lorsqu'une exception se produit dans une coroutine fille, leJobparent est annulé, ce qui entraîne l'annulation de toutes ses autres coroutines filles. L'exception est propagée vers le haut.SupervisorJob: LeSupervisorJobparent n'est pas annulé lorsqu'une exception se produit dans une coroutine fille. Seule la coroutine dans laquelle l'exception s'est produite est annulée. Cela est utile lorsque vous souhaitez que l'annulation d'une tâche fille n'affecte pas les autres.CoroutineScoperacine : Si l'exception atteint leCoroutineScoperacine (par exemple,GlobalScopeou un scope créé avecCoroutineScopesansJob), elle est transmise au gestionnaire global d'exceptionsCoroutineExceptionHandler. Par défaut, si aucun gestionnaire n'est enregistré, l'exception est enregistrée dansSystem.err.
-
Exception capturée : Si l'exception est capturée à l'aide d'un bloc
try-catchà l'intérieur de la coroutine, elle est traitée localement, et la coroutine continue son exécution après le bloccatch, si cela est possible. L'exception n'est pas propagée vers le haut. -
Exceptions liées à l'annulation (par exemple,
CancellationException) : Ces exceptions sont particulières. Elles sont utilisées pour le mécanisme d'annulation des coroutines et sont généralement ignorées par la plupart des gestionnaires d'exceptions par défaut. Elles ne provoquent pas d'échec fatale duJobparent par défaut. -
Exceptions dans
async: La coroutine lancée viaasyncplace l'exception dans sonDeferred. L'exception n'est propagée que lors de l'appel de.await()sur ceDeferred. Jusqu'à ce moment, l'exception est "cachée".
import kotlinx.coroutines.*
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob())
scope.launch {
try {
println("Coroutine 1 démarrée")
delay(100)
throw RuntimeException("Quelque chose a mal tourné dans Coroutine 1")
} catch (e: Exception) {
println("Coroutine 1 a capturé l'exception : ${e.message}")
}
}
scope.launch {
println("Coroutine 2 démarrée")
delay(500)
println("Coroutine 2 terminée")
}
delay(1000) // Attendre pour voir la sortie
scope.cancel() // Annuler le scope
}
Dans cet exemple, l'exception dans la Coroutine 1 est capturée, et la Coroutine 2 continue son exécution car SupervisorJob est utilisé. Si un Job normal était utilisé à la place, l'exception dans la Coroutine 1 entraînerait l'annulation de la Coroutine 2.