0Pricing
Kotlin Academy · Lektion

CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions

Installieren Sie einen CoroutineExceptionHandler, um unbehandelte Exceptions zu protokollieren oder zu behandeln.

CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was ist CoroutineExceptionHandler?

CoroutineExceptionHandler ist ein Kontextelement, das nicht abgefangene Ausnahmen aus Coroutines behandelt, für die kein catch-Handler vorhanden ist. Er dient als letzte Absicherung.

import kotlinx.coroutines.*
val handler = CoroutineExceptionHandler { context, exception ->
    println("Caught unhandled: ${exception.message}")
}
fun main() = runBlocking {
    val scope = CoroutineScope(Dispatchers.Default + handler)
    scope.launch { throw RuntimeException("oops") }
    delay(100)
}

Nur für Root-Coroutines

CoroutineExceptionHandler fängt nur Ausnahmen aus Root-Coroutines ab, die direkt in einem Scope gestartet wurden. Untergeordnete Coroutines geben Ausnahmen an ihre übergeordnete Coroutine weiter, nicht an den Handler.

import kotlinx.coroutines.*
val handler = CoroutineExceptionHandler { _, e -> println("Handler: ${e.message}") }
fun main() = runBlocking {
    // Root coroutine — handler fires:
    CoroutineScope(handler).launch {
        throw RuntimeException("root error")
    }
    delay(100)
    // NOT handler (child of coroutineScope):
    // launch { launch { throw RuntimeException() } }
}

Unterdrückt die Ausnahme nicht

Der Handler wird nachdem die Ausnahme die Coroutine bereits abgebrochen hat, aufgerufen. Er dient der Protokollierung, der Absturzberichterstattung oder der Bereinigung – nicht zum Fortsetzen der Ausführung.

import kotlinx.coroutines.*
val handler = CoroutineExceptionHandler { _, e ->
    println("[CrashReport] ${e::class.simpleName}: ${e.message}")
    // send to Crashlytics, Sentry, etc.
}
fun main() = runBlocking {
    CoroutineScope(SupervisorJob() + handler).apply {
        launch { throw IllegalStateException("state error") }
        launch { delay(100); println("still alive") }
        delay(200)
        cancel()
    }
}

Handler + SupervisorJob

Die Kombination aus SupervisorJob + CoroutineExceptionHandler ist das Standardmuster für langlebige Scopes: Untergeordnete Coroutines schlagen unabhängig voneinander fehl und nicht behandelte Fehler werden protokolliert.

import kotlinx.coroutines.*
class AppScope {
    private val handler = CoroutineExceptionHandler { _, e ->
        println("Uncaught: ${e.message}")
    }
    val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default + handler)
}
fun main() = runBlocking {
    val app = AppScope()
    app.scope.launch { throw RuntimeException("task failed") }
    app.scope.launch { delay(100); println("other task ok") }
    delay(200)
    app.scope.cancel()
}

Handler mit async

Bei async werden Ausnahmen im Deferred gespeichert und bei await() ausgelöst. Der Handler wird für async NICHT aufgerufen, sofern das Deferred nicht abgewartet wird.

import kotlinx.coroutines.*
val handler = CoroutineExceptionHandler { _, e -> println("Handler: ${e.message}") }
fun main() = runBlocking {
    val scope = CoroutineScope(SupervisorJob() + handler)
    val deferred = scope.async { throw RuntimeException("async error") }
    try {
        deferred.await()  // exception thrown here
    } catch (e: RuntimeException) {
        println("Caught from await: ${e.message}")
    }
    delay(50)
    scope.cancel()
}

Vergleich mit Thread.UncaughtExceptionHandler

Anders als Javas UncaughtExceptionHandler ist der Handler von Kotlin Teil des Coroutine-Kontexts und gilt nur für die Coroutines innerhalb dieses Scopes.

import kotlinx.coroutines.*
// Java style (applies to threads):
Thread.setDefaultUncaughtExceptionHandler { t, e ->
    println("Thread ${t.name} threw: ${e.message}")
}
// Kotlin coroutine style (applies to coroutines in scope):
val handler = CoroutineExceptionHandler { _, e ->
    println("Coroutine threw: ${e.message}")
}
fun main() = runBlocking { println("Handlers target different concurrency models") }

Protokollierungsmuster mit MDC

In Serveranwendungen kann der Handler Informationen aus dem Coroutine-Kontext, etwa Anfrage-IDs, erfassen, um sie vor der Weiterleitung an das Logging-Framework für eine strukturierte Protokollierung zu verwenden.

import kotlinx.coroutines.*
val handler = CoroutineExceptionHandler { ctx, e ->
    val jobName = ctx[CoroutineName]?.name ?: "unknown"
    println("[${jobName}] ERROR: ${e.message}")
}
fun main() = runBlocking {
    CoroutineScope(SupervisorJob() + handler).launch(CoroutineName("DataLoader")) {
        throw RuntimeException("fetch failed")
    }
    delay(100)
}

Integration der Absturzberichterstattung

Verwenden Sie den Handler, um nicht abgefangene Ausnahmen an Dienste zur Absturzberichterstattung wie Firebase Crashlytics oder Sentry weiterzuleiten.

import kotlinx.coroutines.*
object CrashReporter {
    fun record(e: Throwable) = println("[Crashlytics] ${e.message}")
}
val handler = CoroutineExceptionHandler { _, e ->
    if (e !is CancellationException) CrashReporter.record(e)
}
val appScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + handler)
fun main() = runBlocking {
    appScope.launch { throw RuntimeException("unhandled in production") }
    delay(100)
    appScope.cancel()
}

Vererbung des Handlers

Der Handler aus dem übergeordneten Kontext wird von untergeordneten Coroutines NICHT automatisch übernommen. Er muss sich im Kontext der Root-Coroutine befinden, damit er aufgerufen wird.

import kotlinx.coroutines.*
val handler = CoroutineExceptionHandler { _, e -> println("Handler: ${e.message}") }
fun main() = runBlocking {
    // Handler only fires at root level:
    CoroutineScope(SupervisorJob() + handler).launch {
        // Child of root — exception propagates to root handler:
        launch { throw RuntimeException("nested") }
    }
    delay(100)
}

Zusammenfassung der Best Practices

Installieren Sie immer einen CoroutineExceptionHandler in Ihren App- oder Feature-Scopes. Protokollieren Sie jede Ausnahme, die keine CancellationException ist. Verlassen Sie sich niemals auf ihn für die Ablaufsteuerung – er dient ausschließlich der Beobachtbarkeit.

import kotlinx.coroutines.*
val globalHandler = CoroutineExceptionHandler { ctx, e ->
    if (e !is CancellationException) {
        println("[ERROR] ${ctx[CoroutineName]?.name}: ${e.message}")
    }
}
val appScope = CoroutineScope(SupervisorJob() + Dispatchers.Default + globalHandler)
fun main() = runBlocking {
    appScope.launch(CoroutineName("Auth")) { throw RuntimeException("token expired") }
    delay(100); appScope.cancel()
}

Kurze Überprüfung

Für welchen Coroutine-Typ wird CoroutineExceptionHandler NICHT automatisch aufgerufen?

Zusammenfassung

CoroutineExceptionHandler ist ein Beobachter als letzte Absicherung für nicht abgefangene Ausnahmen in Root-Coroutines. Kombinieren Sie ihn für langlebige Scopes mit SupervisorJob. Verwenden Sie ihn für Protokollierung und Absturzberichterstattung – niemals für die Ablaufsteuerung.

Häufig gestellte Fragen

Ist die Lektion „CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions“ kostenlos?

Ja — der vollständige Text von „CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions“?

Installieren Sie einen CoroutineExceptionHandler, um unbehandelte Exceptions zu protokollieren oder zu behandeln. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. SupervisorJob vs. Job: Fehlerisolierung
  2. CoroutineExceptionHandler: globaler Handler für unbehandelte Exceptions
  3. Exception-Weitergabe bei async/await
  4. Robuste Coroutine-Architekturen entwerfen
← Zurück zu Kotlin Academy