Kotlin Academy · Lektion

Genudløsning og kædning af exceptions

Genudløs exceptions efter behov, og indkapsl fejl på lavere niveau med kædede årsager.

Lektion 4 af 413 trin

Genudløsning og kædning af exceptions er en gratis Kotlin Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Kotlin Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Kotlin Academy-kurset indeholder 4 lektioner i alt.

Genkastning og indpakning

Nogle gange indfanger du kun en undtagelse for at logge, indpakke eller konvertere den, før du lader en mere specifik undtagelse blive ført videre. Kotlin gør dette på en idiomatisk måde.

Almindelig genkastning

For at kaste en undtagelse videre skal du blot bruge throw e igen — videreførslen fortsætter til den næste håndtering.

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}")
    }
}

Indpakning med en brugerdefineret undtagelse

Videregiv den oprindelige undtagelse som cause, når du opretter en ny, så kæden bevares.

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}")
    }
}

Undersøgelse af årsagskæden

Egenskaben cause forbinder med den forrige undtagelse. Gå gennem kæden for at udskrive hele den grundlæggende årsag.

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

Selektiv genkastning

Indfang en bred type, og kast den videre, hvis den IKKE passer til dit forventede tilfælde.

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
}

Tilføjelse af kontekst

Indpak med en domæneundtagelse for at tilføje kontekst, som den oprindelige undtagelse manglede, f.eks. inddata, et anmodnings-id osv.

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}") }
}

Mist aldrig staksporet

Når du indpakker, skal du altid videregive den oprindelige undtagelse som cause — opret aldrig bare en ny undtagelse med den samme meddelelse uden en årsag. Staksporet er afgørende for din fejlfinding.

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}")
    }
}

Genkastning uden indpakning

Hvis logning er alt, hvad du har brug for, skal du blot bruge throw e efter logningen — indpakning er ikke nødvendig.

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 til oprydning under genkastning

Brug finally til at rydde ressourcer op, selv når du kaster en undtagelse videre.

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

Undertrykte undtagelser

Hvis finally selv kaster en undtagelse, undertrykkes den oprindelige undtagelse som standard. Brug addSuppressed til at bevare begge.

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

Anti-mønster: Slugning efterfulgt af genkastning af en anden undtagelse

At fange én undtagelse og kaste en ny, uvedkommende undtagelse (uden årsag) ødelægger oplysninger til fejlfinding. Send altid cause med.
// 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!") }

Hurtigt tjek

Hvad skal du gøre for at bevare det oprindelige stakspor, når du pakker en undtagelse ind i en ny?

Opsummering

For at kaste videre: throw e. For at pakke ind: kast en ny undtagelse med cause = e. Bevar altid årsagskæden – konstruer aldrig en indpakning uden årsag. Brug finally til oprydning og addSuppressed, når selve oprydningen mislykkes.
Gratis at komme i gang

Lær Kotlin med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
51
Lektioner
203

Ofte stillede spørgsmål

Er lektionen “Genudløsning og kædning af exceptions” gratis?

Ja — alle 3 lektioner i læringssporet Kotlin Academy, inklusive “Genudløsning og kædning af exceptions”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Kotlin Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Genudløsning og kædning af exceptions”?

Genudløs exceptions efter behov, og indkapsl fejl på lavere niveau med kædede årsager. Du øver dig i Kotlin Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Kotlin Academy?

Der kræves ingen tidligere erfaring. Kotlin Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Genudløsning og kædning af exceptions”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Kotlin Academy-lektion?

Ja. Alle Kotlin Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. try/catch/finally som et udtryk
  2. Oprettelse af tilpassede exception-klasser
  3. runCatching og Result
  4. Genudløsning og kædning af exceptions
← Tilbage til Kotlin Academy