Sometimes things go wrong when your program runs. Exception handling in coroutines helps you catch and manage these problems smoothly without crashing your app.
Exception handling in coroutines in Kotlin
try { // coroutine code that might throw an exception } catch (e: Exception) { // handle the exception here }
You can use try-catch blocks inside coroutines just like in normal code.
For coroutine builders like launch, exceptions are handled differently and may need a CoroutineExceptionHandler.
try-catch.runBlocking {
try {
val result = riskyOperation()
println("Result: $result")
} catch (e: Exception) {
println("Caught error: ${e.message}")
}
}CoroutineExceptionHandler to catch exceptions from a launch coroutine.val handler = CoroutineExceptionHandler { _, exception -> println("Caught in handler: ${exception.message}") } val job = GlobalScope.launch(handler) { throw RuntimeException("Oops!") } job.join()
This program starts a coroutine that throws an exception. The CoroutineExceptionHandler catches it and prints a message. The program continues running after handling the error.
import kotlinx.coroutines.* fun main() = runBlocking { val handler = CoroutineExceptionHandler { _, exception -> println("Caught exception: ${exception.message}") } val job = launch(handler) { println("Starting coroutine") delay(100) throw IllegalArgumentException("Something went wrong") } job.join() println("Coroutine finished") }
Exceptions in launch coroutines are uncaught by default unless you provide a CoroutineExceptionHandler.
Exceptions in async coroutines are thrown when you call await(), so handle exceptions there.
Always handle exceptions to keep your app stable and user-friendly.
Use try-catch inside coroutines to catch errors directly.
Use CoroutineExceptionHandler to catch exceptions from launch coroutines.
Handling exceptions keeps your app running smoothly even when errors happen.
Practice
launch?Solution
Step 1: Understand coroutine exception handling basics
Exceptions insidelaunchcoroutines are caught bytry-catchblocks within the coroutine code itself.Step 2: Identify correct method to catch exceptions
Thecatchmethod does not exist on coroutine builders, andfinallyoutside coroutine does not catch coroutine exceptions.Final Answer:
Use try-catch block inside the coroutine code -> Option AQuick Check:
try-catch inside coroutine = correct way [OK]
- Thinking catch method exists on coroutine builders
- Using finally block outside coroutine to catch exceptions
- Assuming exceptions cannot be caught in coroutines
CoroutineExceptionHandler in Kotlin?Solution
Step 1: Recall CoroutineExceptionHandler signature
It takes a lambda with two parameters:contextandexception.Step 2: Match correct syntax
val handler = CoroutineExceptionHandler { context, exception -> println(exception) } correctly uses the two parameters in the lambda. Other options miss parameters or have wrong syntax.Final Answer:
val handler = CoroutineExceptionHandler { context, exception -> println(exception) } -> Option DQuick Check:
CoroutineExceptionHandler requires (context, exception) lambda [OK]
- Omitting context parameter in lambda
- Passing parameters incorrectly
- Using invalid constructor syntax
import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught: ${exception.message}")
}
val job = launch(handler) {
throw IllegalArgumentException("Invalid argument")
}
job.join()
println("Done")
}Solution
Step 1: Understand CoroutineExceptionHandler usage
The handler catches exceptions thrown inside thelaunchcoroutine and prints the message.Step 2: Trace program output
The exception message "Invalid argument" is printed by the handler, then "Done" is printed afterjob.join().Final Answer:
Caught: Invalid argument Done -> Option AQuick Check:
Exception caught by handler, then Done printed [OK]
- Expecting uncaught exception crash
- Missing that handler catches exception
- Ignoring job.join() effect
import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, exception ->
println("Error: ${exception.message}")
}
val job = async(handler) {
throw RuntimeException("Failure")
}
job.await()
}Solution
Step 1: Understand exception handling difference between launch and async
Exceptions inasyncare propagated via the deferred result and must be caught bytry-catchonawait().Step 2: Analyze why CoroutineExceptionHandler fails here
CoroutineExceptionHandler does not catch exceptions fromasynccoroutines because they are deferred untilawait().Final Answer:
CoroutineExceptionHandler does not catch exceptions from async coroutines -> Option CQuick Check:
async exceptions need try-catch on await() [OK]
- Expecting CoroutineExceptionHandler to catch async exceptions
- Ignoring need for try-catch on await()
- Misunderstanding handler lambda parameters
launch coroutines in a Kotlin app and log errors without stopping other coroutines. Which approach is best?Solution
Step 1: Understand exception handling for multiple launch coroutines
Using a sharedCoroutineExceptionHandleron the parent scope catches exceptions from all childlaunchcoroutines without cancelling siblings.Step 2: Evaluate other options
Wrapping each coroutine in try-catch is verbose and error-prone; async with await is for deferred results; SupervisorJob alone does not handle exceptions or logging.Final Answer:
Attach a shared CoroutineExceptionHandler to the parent scope and launch coroutines within it -> Option BQuick Check:
Shared handler on parent scope manages launch exceptions [OK]
- Ignoring shared handler benefits
- Using async instead of launch for fire-and-forget
- Not handling exceptions leads to crashes
Ready to prove it?
Pass the test and this pattern moves unknown
