Quelles méthodes de gestion des erreurs dans les coroutines connaissez-vous?
sobes.tech IA
Réponse de l'IA
-
Utilisation des blocs
try...catch. Méthode standard pour gérer les exceptions. Fonctionne à l'intérieur d'une coroutine.// Utilisation de try-catch suspend fun fetchData(): String { return try { // Opération pouvant lancer une exception throw Exception("Erreur lors du chargement des données") "Données chargées avec succès" } catch (e: Exception) { "Erreur: ${e.message}" } }try...catchn'est pas adapté pour gérer les exceptions non attrapées lancées par des coroutines enfants, exécutées dans un autreCoroutineScope. -
CoroutineExceptionHandler. Intercepte les exceptions non gérées lancées par des coroutines qui s'exécutent dans ceCoroutineScopeou sesCoroutineScopeenfants.// CoroutineExceptionHandler val handler = CoroutineExceptionHandler { _, exception -> println("Exception interceptée: $exception") } // Utilisation de CoroutineExceptionHandler GlobalScope.launch(handler) { // Coroutine pouvant lancer une exception throw Exception("Erreur dans la coroutine") }CoroutineExceptionHandlerne s'active que pour les exceptions non gérées par le mécanisme de concurrence structurée. -
SupervisorJobetsupervisorScope. Contrairement à unJobclassique, lorsqu'une coroutine fille avec erreur entraîne l'annulation duJobparent,SupervisorJobne l'annule pas.supervisorScopecrée unCoroutineScopeavec unSupervisorJob.// Utilisation de supervisorScope suspend fun loadMultipleData() = supervisorScope { val data1 = async { // Peut lancer une exception throw Exception("Erreur dans données 1") "Données 1" } val data2 = async { "Données 2" } // Peut gérer l'exception pour une async spécifique try { println("Résultat 1: ${data1.await()}") } catch (e: Exception) { println("Erreur lors du chargement des données 1: ${e.message}") } println("Résultat 2: ${data2.await()}") }Utilisé pour des tâches enfants indépendantes, où l'erreur d'une ne doit pas affecter les autres. Ne remplace pas
try...catchouCoroutineExceptionHandler, mais modifie le comportement de propagation des exceptions. -
Propagation des exceptions en concurrence structurée. Par défaut, une exception dans une coroutine enfant annule la coroutine parent et tous ses frères.
// Exemple de propagation d'exception runBlocking { val job = launch { launch { // Coroutine enfant 1 delay(100) throw Exception("Erreur dans l'enfant 1") } launch { // Coroutine enfant 2 delay(200) println("Enfant 2 terminée") } } try { job.join() } catch (e: Exception) { println("Exception interceptée dans le parent: $e") } }C'est le comportement de base de la concurrence structurée, qui aide à éviter les fuites de ressources et d'états.
-
Utilisation de
asyncavecawait(). Les exceptions lancées dansasyncne se propagent pas automatiquement. Elles sont stockées dansDeferredet ne sont levées qu'au moment de l'appel àawait().// Gestion des exceptions avec async/await suspend fun safeAsyncCall() = coroutineScope { val deferred = async { throw Exception("Erreur dans async") "Résultat de async" } try { val result = deferred.await() println("Résultat: $result") } catch (e: Exception) { println("Exception interceptée depuis async: ${e.message}") } }Cela permet de gérer sélectivement les erreurs pour chaque tâche asynchrone.
| Méthode | Objectif | Gère les uncaught? | Change la propagation? |
|---|---|---|---|
try...catch |
Gestion des exceptions dans la coroutine courante | Non | Non |
CoroutineExceptionHandler |
Capture des exceptions non gérées dans Scope | Oui | Non |
SupervisorJob/Scope |
Modifie le comportement de propagation des exceptions | Non | Oui |
| Concurrence structurée | Annulation automatique en cas d'erreur | Oui | Oui |
async + await() |
Propagation différée des exceptions | Non | Oui (avant await) |