0Pricing
Kotlin Academy · Leçon

Relancer des exceptions et chaînage des exceptions

Relancez certaines exceptions et enveloppez les erreurs de niveau inférieur en conservant leur cause.

Relancer des exceptions et chaînage des exceptions est une leçon Kotlin Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Kotlin Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Kotlin Academy comprend 4 leçons au total.

Relancer et envelopper les exceptions

Parfois, vous interceptez une exception uniquement pour la journaliser, l’envelopper ou la convertir avant de laisser une exception plus spécifique se propager. Kotlin rend cette pratique idiomatique.

Relance simple

Pour relancer une exception, utilisez simplement throw e — la propagation continue jusqu’au gestionnaire suivant.

fun main() {
    try {
        try { "x".toInt() }
        catch (e: NumberFormatException) {
            println("logging: ${e.message}")
            throw e // re-throw original
        }
    } catch (e: NumberFormatException) {
        println("outer caught: ${e.message}")
    }
}

Envelopper avec une exception personnalisée

Transmettez l’exception d’origine comme cause lors de la construction de la nouvelle exception afin de préserver la chaîne.

class ParseException(msg: String, cause: Throwable) : RuntimeException(msg, cause)
fun main() {
    try {
        try { "xyz".toInt() }
        catch (e: NumberFormatException) {
            throw ParseException("could not parse user input", e)
        }
    } catch (e: ParseException) {
        println("got: ${e.message}")
        println("cause: ${e.cause?.message}")
    }
}

Inspecter la chaîne des causes

La propriété cause renvoie vers l’exception précédente. Parcourez-la pour afficher la cause racine complète.

fun main() {
    val e = RuntimeException("top",
        RuntimeException("middle",
            RuntimeException("root")))
    var current: Throwable? = e
    while (current != null) {
        println(current.message)
        current = current.cause
    }
}

Relance sélective

Interceptez un type général, puis relancez l’exception s’il ne correspond PAS au cas attendu.

fun parseRequired(s: String): Int {
    try {
        return s.toInt()
    } catch (e: NumberFormatException) {
        if (s.isBlank()) return 0
        throw e // unexpected — let it propagate
    }
}
fun main() {
    println(parseRequired("42"))
    println(parseRequired(""))
    // parseRequired("abc") // throws
}

Ajouter du contexte

Enveloppez l’exception avec une exception métier pour ajouter le contexte qui manquait à l’originale — entrée, identifiant de requête, etc.

class UploadError(msg: String, cause: Throwable) : RuntimeException(msg, cause)
fun upload(file: String) {
    try { throw RuntimeException("disk full") }
    catch (e: Throwable) { throw UploadError("uploading $file failed", e) }
}
fun main() {
    try { upload("photo.jpg") }
    catch (e: UploadError) { println("${e.message} <- ${e.cause?.message}") }
}

Ne pas perdre la trace de la pile

Lors de l’enveloppement, transmettez toujours l’exception d’origine comme cause — ne créez jamais simplement une nouvelle exception avec le même message mais sans cause. La trace de la pile est indispensable au débogage.

class Wrapped(m: String, cause: Throwable) : RuntimeException(m, cause)
fun main() {
    try {
        try { error("inner") }
        catch (e: Throwable) { throw Wrapped("outer", e) }
    } catch (e: Wrapped) {
        println("message: ${e.message}")
        println("cause: ${e.cause?.message}")
    }
}

Relancer sans envelopper

Si la journalisation est tout ce dont vous avez besoin, utilisez simplement throw e après l’appel de journalisation — aucun enveloppement n’est nécessaire.

fun risky() {
    try { throw IllegalStateException("oops") }
    catch (e: IllegalStateException) {
        println("Logging before rethrow: ${e.message}")
        throw e
    }
}
fun main() {
    try { risky() }
    catch (e: IllegalStateException) { println("outer: ${e.message}") }
}

finally pour le nettoyage lors d’une relance

Utilisez finally pour nettoyer les ressources, même lors d’une relance.

fun process() {
    try {
        throw RuntimeException("failure")
    } finally {
        println("cleanup ran")
    }
}
fun main() {
    try { process() }
    catch (e: RuntimeException) { println("caught: ${e.message}") }
}

Exceptions supprimées

Si finally lui-même lance une exception, l’exception d’origine est supprimée par défaut. Utilisez addSuppressed pour conserver les deux exceptions.

fun main() {
    val primary = RuntimeException("primary")
    val secondary = RuntimeException("from cleanup")
    primary.addSuppressed(secondary)
    println(primary.suppressed.joinToString { it.message ?: "?" })
}

Anti-pattern&nbsp;: avaler une exception puis en lancer une autre

Intercepter une exception et en lancer une nouvelle sans rapport (sans cause) détruit les informations de débogage. Transmettez toujours cause.

// BAD
// catch (e: IOException) { throw RuntimeException("error") }
// GOOD
// catch (e: IOException) { throw RuntimeException("error reading config", e) }
fun main() { println("Pass cause when re-throwing!") }

Vérification rapide

Lorsque vous encapsulez une exception dans une nouvelle exception, que devez-vous faire pour préserver la trace d'appels d'origine ?

Récapitulatif

Pour relancer : throw e. Pour encapsuler : lancez une nouvelle exception avec cause = e. Préservez toujours la chaîne des causes : ne construisez jamais d'enveloppe sans cause. Utilisez finally pour le nettoyage, et addSuppressed lorsque le nettoyage échoue lui-même.

Questions Fréquemment Posées

La leçon « Relancer des exceptions et chaînage des exceptions » est-elle gratuite ?

Oui — le texte complet de « Relancer des exceptions et chaînage des exceptions » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Kotlin Academy, passe à CoddyKit PRO. Le cours Kotlin Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Relancer des exceptions et chaînage des exceptions » ?

Relancez certaines exceptions et enveloppez les erreurs de niveau inférieur en conservant leur cause. Tu pratiques Kotlin Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Kotlin Academy ?

Aucune expérience préalable n'est requise. Kotlin Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Relancer des exceptions et chaînage des exceptions » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Kotlin Academy ?

Oui. Chaque leçon Kotlin Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. try/catch/finally comme expression
  2. Créer des classes d’exception personnalisées
  3. runCatching et Result
  4. Relancer des exceptions et chaînage des exceptions
← Retour à Kotlin Academy