Bird
Raised Fist0
Kotlinprogramming~10 mins

Exception handling in coroutines in Kotlin - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Exception handling in coroutines
Start Coroutine
↓
Try block runs
↓
Exception thrown?
No→Coroutine completes normally
Yes↓
Catch block handles exception
↓
Coroutine resumes or ends
↓
Finally block runs (optional)
↓
Coroutine ends
The coroutine starts and runs code inside a try block. If an exception happens, it jumps to the catch block to handle it, then continues or ends. Finally block runs last if present.
Execution Sample
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
  try {
    launch { throw Exception("Error in coroutine") }
  } catch (e: Exception) {
    println("Caught: ${e.message}")
  }
}
This code launches a coroutine that throws an exception, which is NOT caught by the outer catch block.
Execution Table
StepActionEvaluationResult
1Start runBlocking scopeNo exceptionScope started
2Enter try blockNo exception yetReady to launch coroutine
3launch coroutineCoroutine startedCoroutine running asynchronously
4Coroutine throws ExceptionException thrown inside coroutineException propagates
5Catch block in main try-catch?No, exception is in coroutine contextCatch block NOT triggered here
6Coroutine fails silently (default)Exception not caught by outer tryException logged by coroutine machinery
7runBlocking completesNo exception caughtProgram ends without printing catch message
💡 Coroutine exception is not caught by outer try-catch because it runs asynchronously; coroutine machinery handles it.
Variable Tracker
VariableStartAfter Step 3After Step 4Final
Coroutine StateNot startedRunningFailed with ExceptionEnded
Exception caughtNoNoNoNo
Key Moments - 2 Insights
Why doesn't the catch block catch the exception thrown inside the coroutine?
Because the coroutine runs asynchronously, the exception happens outside the try block's direct scope. The try-catch only catches exceptions thrown in the same thread and scope, not inside launched coroutines (see execution_table step 5).
How can exceptions inside coroutines be caught properly?
You can use CoroutineExceptionHandler or try-catch inside the coroutine itself. The outer try-catch won't catch exceptions from launched coroutines (see execution_table step 6).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, at which step does the coroutine throw an exception?
AStep 3
BStep 4
CStep 5
DStep 6
💡 Hint
Check the 'Action' and 'Evaluation' columns for when the exception occurs.
According to the variable tracker, what is the coroutine state after step 4?
ARunning
BNot started
CFailed with Exception
DEnded
💡 Hint
Look at the 'Coroutine State' row and the 'After Step 4' column.
If you want the outer try-catch to catch coroutine exceptions, what should you do?
AUse CoroutineExceptionHandler or try-catch inside coroutine
BLaunch coroutine inside try block
CNothing, outer try-catch always catches coroutine exceptions
DUse runBlocking without try-catch
💡 Hint
Refer to key_moments explanation about catching exceptions inside coroutines.
Concept Snapshot
Exception handling in coroutines:
- Exceptions inside launched coroutines are not caught by outer try-catch.
- Use try-catch inside coroutine or CoroutineExceptionHandler.
- Coroutine exceptions propagate asynchronously.
- runBlocking waits for coroutines but doesn't catch their exceptions by default.
Full Transcript
This visual execution shows how exceptions behave in Kotlin coroutines. When a coroutine launched inside a try block throws an exception, the outer catch block does not catch it because the coroutine runs asynchronously. The exception is handled by coroutine machinery, not the outer try-catch. To catch exceptions properly, you must use try-catch inside the coroutine or a CoroutineExceptionHandler. The execution table traces each step, showing the coroutine state and exception flow. The variable tracker highlights how the coroutine state changes from running to failed. Key moments clarify common confusions about exception scope and handling. The quiz tests understanding of when exceptions occur and how to catch them.

Practice

(1/5)
1. What is the primary way to catch exceptions inside a Kotlin coroutine launched with launch?
easy
A. Use try-catch block inside the coroutine code
B. Use catch method on the coroutine builder
C. Use finally block outside the coroutine
D. Exceptions cannot be caught in coroutines

Solution

  1. Step 1: Understand coroutine exception handling basics

    Exceptions inside launch coroutines are caught by try-catch blocks within the coroutine code itself.
  2. Step 2: Identify correct method to catch exceptions

    The catch method does not exist on coroutine builders, and finally outside coroutine does not catch coroutine exceptions.
  3. Final Answer:

    Use try-catch block inside the coroutine code -> Option A
  4. Quick Check:

    try-catch inside coroutine = correct way [OK]
Hint: Catch exceptions inside coroutine with try-catch [OK]
Common Mistakes:
  • Thinking catch method exists on coroutine builders
  • Using finally block outside coroutine to catch exceptions
  • Assuming exceptions cannot be caught in coroutines
2. Which of the following is the correct syntax to define a CoroutineExceptionHandler in Kotlin?
easy
A. val handler = CoroutineExceptionHandler { println(exception) }
B. val handler = CoroutineExceptionHandler { exception -> println(exception) }
C. val handler = CoroutineExceptionHandler(context, exception -> println(exception))
D. val handler = CoroutineExceptionHandler { context, exception -> println(exception) }

Solution

  1. Step 1: Recall CoroutineExceptionHandler signature

    It takes a lambda with two parameters: context and exception.
  2. 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.
  3. Final Answer:

    val handler = CoroutineExceptionHandler { context, exception -> println(exception) } -> Option D
  4. Quick Check:

    CoroutineExceptionHandler requires (context, exception) lambda [OK]
Hint: CoroutineExceptionHandler lambda needs context and exception [OK]
Common Mistakes:
  • Omitting context parameter in lambda
  • Passing parameters incorrectly
  • Using invalid constructor syntax
3. What will be the output of the following Kotlin code?
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")
}
medium
A. Caught: Invalid argument Done
B. Exception in thread "main" java.lang.IllegalArgumentException: Invalid argument
C. Done
D. Caught: null Done

Solution

  1. Step 1: Understand CoroutineExceptionHandler usage

    The handler catches exceptions thrown inside the launch coroutine and prints the message.
  2. Step 2: Trace program output

    The exception message "Invalid argument" is printed by the handler, then "Done" is printed after job.join().
  3. Final Answer:

    Caught: Invalid argument Done -> Option A
  4. Quick Check:

    Exception caught by handler, then Done printed [OK]
Hint: ExceptionHandler prints message, then main continues [OK]
Common Mistakes:
  • Expecting uncaught exception crash
  • Missing that handler catches exception
  • Ignoring job.join() effect
4. Identify the error in this Kotlin coroutine exception handling code:
import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Error: ${exception.message}")
    }
    val job = async(handler) {
        throw RuntimeException("Failure")
    }
    job.await()
}
medium
A. Missing try-catch block inside async coroutine
B. The handler lambda parameters are incorrect
C. CoroutineExceptionHandler does not catch exceptions from async coroutines
D. Using runBlocking incorrectly

Solution

  1. Step 1: Understand exception handling difference between launch and async

    Exceptions in async are propagated via the deferred result and must be caught by try-catch on await().
  2. Step 2: Analyze why CoroutineExceptionHandler fails here

    CoroutineExceptionHandler does not catch exceptions from async coroutines because they are deferred until await().
  3. Final Answer:

    CoroutineExceptionHandler does not catch exceptions from async coroutines -> Option C
  4. Quick Check:

    async exceptions need try-catch on await() [OK]
Hint: Use try-catch on await() for async exceptions [OK]
Common Mistakes:
  • Expecting CoroutineExceptionHandler to catch async exceptions
  • Ignoring need for try-catch on await()
  • Misunderstanding handler lambda parameters
5. You want to handle exceptions from multiple launch coroutines in a Kotlin app and log errors without stopping other coroutines. Which approach is best?
hard
A. Use async coroutines and catch exceptions on await()
B. Attach a shared CoroutineExceptionHandler to the parent scope and launch coroutines within it
C. Wrap each coroutine body in a try-catch block and ignore exceptions
D. Use SupervisorJob without any exception handling

Solution

  1. Step 1: Understand exception handling for multiple launch coroutines

    Using a shared CoroutineExceptionHandler on the parent scope catches exceptions from all child launch coroutines without cancelling siblings.
  2. 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.
  3. Final Answer:

    Attach a shared CoroutineExceptionHandler to the parent scope and launch coroutines within it -> Option B
  4. Quick Check:

    Shared handler on parent scope manages launch exceptions [OK]
Hint: Use shared CoroutineExceptionHandler on parent for launch coroutines [OK]
Common Mistakes:
  • Ignoring shared handler benefits
  • Using async instead of launch for fire-and-forget
  • Not handling exceptions leads to crashes
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard