CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä
Asentakaa CoroutineExceptionHandler kirjaamaan tai palauttamaan käsittelemättömistä poikkeuksista.
CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä on ilmainen Kotlin Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Kotlin Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Kotlin Academy-kurssilla on yhteensä 4 oppituntia.
Mikä on CoroutineExceptionHandler?
CoroutineExceptionHandler on kontekstielementti, joka käsittelee kiinniottamattomat poikkeukset korutiineista, joissa ei ole catch-käsittelijää. Se toimii viimeisenä keinona.
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)
}Vain juurikorutiineille
CoroutineExceptionHandler ottaa kiinni poikkeuksia vain root-korutiineista, jotka käynnistetään suoraan scopessa. Lapsikorutiinit välittävät poikkeukset vanhemmalleen, eivät käsittelijälle.
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() } }
}Poikkeusta ei vaimenneta
Käsittelijä kutsutaan sen jälkeen, kun poikkeus on jo peruuttanut korutiinin. Sitä käytetään lokitukseen, kaatumisten raportointiin tai siivoukseen — ei suorituksen jatkamiseen.
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()
}
}Käsittelijä + SupervisorJob
SupervisorJob + CoroutineExceptionHandler -yhdistelmä on pitkäkestoisten scopejen vakiomalli: lapset epäonnistuvat toisistaan riippumatta ja käsittelemättömät epäonnistumiset kirjataan lokiin.
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()
}Käsittelijä async-operaatioissa
async-operaatioissa poikkeukset tallennetaan Deferred-objektiin ja heitetään await()-kutsun yhteydessä. Käsittelijä EI käynnisty async-operaatioille, ellei deferrediä jätetä odottamatta.
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()
}Thread.UncaughtExceptionHandler-vertailu
Toisin kuin Javan UncaughtExceptionHandler, Kotlinin käsittelijä on osa korutiinin kontekstia ja koskee vain kyseisen scopen korutiineja.
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") }Lokitusmalli MDC:n kanssa
Palvelinsovelluksissa käsittelijä voi kerätä korutiinin kontekstitietoja, kuten pyyntöjen tunnisteita, rakenteista lokitusta varten ennen tietojen välittämistä lokituskehykselle.
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)
}Integrointi kaatumisten raportointiin
Käyttäkää käsittelijää välittääksenne kiinniottamattomat poikkeukset kaatumisten raportointipalveluihin, kuten Firebase Crashlyticsiin tai Sentryyn.
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()
}Käsittelijän periytyminen
Vanhemman kontekstin käsittelijä EI periydy automaattisesti lapsikorutiineille. Sen on oltava juurikorutiinin kontekstissa, jotta se aktivoituu.
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)
}Parhaiden käytäntöjen yhteenveto
Asentakaa CoroutineExceptionHandler aina sovellustason tai ominaisuustason scopeen. Kirjatkaa jokainen muu kuin peruutukseen liittyvä poikkeus lokiin. Älkää koskaan käyttäkö sitä ohjauslogiikkaan — se on tarkoitettu vain havainnointiin.
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()
}Pikatarkistus
Minkä tyyppiselle korutiinille CoroutineExceptionHandler EI käynnisty automaattisesti?
Kertaus
CoroutineExceptionHandler on viimeisenä keinona toimiva tarkkailija juurikorutiinien kiinniottamattomille poikkeuksille. Yhdistäkää se SupervisorJob-rakenteeseen pitkäkestoisissa scopeissa. Käyttäkää sitä lokitukseen ja kaatumisten raportointiin — ei koskaan ohjauslogiikkaan.
Opi Kotlin tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 51
- Oppitunnit
- 203
Usein kysytyt kysymykset
Onko oppitunti ”CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Kotlin Academy-oppimispolun 3 oppituntia, myös oppitunnin “CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Kotlin Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä”?
Asentakaa CoroutineExceptionHandler kirjaamaan tai palauttamaan käsittelemättömistä poikkeuksista. Harjoittelet Kotlin Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Kotlin Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Kotlin Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Kotlin Academy-oppitunnilla?
Kyllä. Jokainen Kotlin Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- SupervisorJob vs Job: virheiden eristäminen
- CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä
- async/await-poikkeusten eteneminen
- Vikasietoisten korutiiniarkkitehtuurien suunnittelu