Bird
Raised Fist0
Kotlinprogramming~20 mins

CancellationException behavior in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
CancellationException Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output when a coroutine is cancelled with CancellationException?
Consider the following Kotlin coroutine code. What will be printed to the console?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            repeat(5) { i ->
                println("Working on $i...")
                delay(100)
            }
        } catch (e: CancellationException) {
            println("Cancelled with message: ${e.message}")
            throw e
        } finally {
            println("Finally block executed")
        }
    }
    delay(250)
    job.cancel(CancellationException("Stop now"))
    job.join()
    println("Main ends")
}
A
Working on 0...
Working on 1...
Working on 2...
Finally block executed
Main ends
B
Working on 0...
Working on 1...
Cancelled with message: Stop now
Finally block executed
Main ends
C
Working on 0...
Working on 1...
Cancelled with message: null
Finally block executed
Main ends
D
Working on 0...
Working on 1...
Exception in thread "main" java.lang.IllegalStateException
Attempts:
2 left
💡 Hint
Think about what happens when a coroutine is cancelled and how CancellationException is handled.
❓ Predict Output
intermediate
2:00remaining
What happens if CancellationException is caught but not rethrown?
Look at this Kotlin coroutine snippet. What will be the output?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            repeat(3) { i ->
                println("Step $i")
                delay(100)
            }
        } catch (e: CancellationException) {
            println("Caught cancellation: ${e.message}")
            // Not rethrowing
        } finally {
            println("Cleanup in finally")
        }
    }
    delay(150)
    job.cancel(CancellationException("Cancelled early"))
    job.join()
    println("Done")
}
A
Step 0
Step 1
Caught cancellation: Cancelled early
Done
B
Step 0
Step 1
Step 2
Cleanup in finally
Done
C
Step 0
Step 1
Caught cancellation: Cancelled early
Cleanup in finally
Done
D
Step 0
Step 1
Exception in thread "main" java.lang.IllegalStateException
Attempts:
2 left
💡 Hint
Consider what happens if the CancellationException is caught but not rethrown in a coroutine.
❓ Predict Output
advanced
2:00remaining
What error is thrown if a coroutine is cancelled with a non-CancellationException?
Analyze this Kotlin coroutine code. What exception will be thrown?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            delay(1000)
        } catch (e: CancellationException) {
            println("Cancelled")
            throw e
        }
    }
    delay(100)
    job.cancel(RuntimeException("Not a cancellation"))
    job.join()
}
Ajava.lang.RuntimeException: Not a cancellation
Bkotlinx.coroutines.CancellationException
Cjava.lang.IllegalStateException
DNo exception, coroutine completes normally
Attempts:
2 left
💡 Hint
What happens if you cancel a coroutine with an exception that is not a CancellationException?
🧠 Conceptual
advanced
2:00remaining
Why should CancellationException be rethrown in coroutine catch blocks?
In Kotlin coroutines, why is it important to rethrow CancellationException after catching it?
ABecause rethrowing allows the coroutine to properly cancel and propagate the cancellation signal to parent coroutines.
BBecause rethrowing automatically restarts the coroutine.
CBecause rethrowing converts the exception into a checked exception.
DBecause rethrowing prevents the coroutine from running any finally blocks.
Attempts:
2 left
💡 Hint
Think about how coroutine cancellation propagates through coroutine hierarchies.
❓ Predict Output
expert
2:00remaining
What is the output when a coroutine's finally block throws a CancellationException?
Examine this Kotlin coroutine code. What will be printed or thrown?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            delay(100)
        } finally {
            println("In finally")
            throw CancellationException("From finally")
        }
    }
    try {
        job.join()
    } catch (e: CancellationException) {
        println("Caught in main: ${e.message}")
    }
}
ANo output, program hangs
B
In finally
Exception in thread "main" java.lang.IllegalStateException
C
In finally
No exception caught, program ends normally
D
In finally
Caught in main: From finally
Attempts:
2 left
💡 Hint
Consider how exceptions thrown in finally blocks are handled in coroutines.

Practice

(1/5)
1. What is the primary purpose of CancellationException in Kotlin coroutines?
easy
A. To stop coroutines cleanly without treating it as an error
B. To indicate a syntax error in coroutine code
C. To force a coroutine to restart automatically
D. To log coroutine execution details

Solution

  1. Step 1: Understand coroutine cancellation

    CancellationException is used to stop coroutines without throwing an error that crashes the program.
  2. Step 2: Differentiate from errors

    Unlike other exceptions, CancellationException signals a normal cancellation, not a failure.
  3. Final Answer:

    To stop coroutines cleanly without treating it as an error -> Option A
  4. Quick Check:

    CancellationException stops coroutines cleanly [OK]
Hint: CancellationException means clean stop, not error [OK]
Common Mistakes:
  • Confusing it with runtime errors
  • Thinking it restarts coroutines
  • Assuming it logs info automatically
2. Which of the following is the correct way to catch a CancellationException in Kotlin?
easy
A. catch (Error e) { /* handle */ }
B. catch (Exception e) { /* handle */ }
C. catch (Throwable e) { /* handle */ }
D. catch (CancellationException e) { /* handle */ }

Solution

  1. Step 1: Identify exception type

    CancellationException is a specific exception type used for coroutine cancellation.
  2. Step 2: Use specific catch block

    To handle cancellation properly, catch CancellationException explicitly.
  3. Final Answer:

    catch (CancellationException e) { /* handle */ } -> Option D
  4. Quick Check:

    Catch CancellationException explicitly [OK]
Hint: Catch CancellationException by its own type [OK]
Common Mistakes:
  • Catching only Exception hides cancellation
  • Using catch (Error) which is unrelated
  • Catching Throwable catches too broadly
3. What will be the output of this Kotlin coroutine code snippet?
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            repeat(3) { i ->
                println("Working $i...")
                delay(100)
            }
        } catch (e: CancellationException) {
            println("Cancelled!")
        } finally {
            println("Cleanup done.")
        }
    }
    delay(150)
    job.cancelAndJoin()
    println("Done")
}
medium
A. Working 0... Working 1... Cancelled! Cleanup done. Done
B. Working 0... Working 1... Working 2... Done
C. Cancelled! Cleanup done. Done
D. Working 0... Cancelled! Done

Solution

  1. Step 1: Trace coroutine execution and cancellation

    The coroutine prints "Working 0..." and "Working 1..." with 100ms delay each, then cancellation occurs after 150ms.
  2. Step 2: Handle CancellationException and finally block

    CancellationException is caught, printing "Cancelled!" and finally block prints "Cleanup done." before main prints "Done".
  3. Final Answer:

    Working 0... Working 1... Cancelled! Cleanup done. Done -> Option A
  4. Quick Check:

    CancellationException caught, cleanup runs, then Done [OK]
Hint: CancellationException triggers catch and finally blocks [OK]
Common Mistakes:
  • Ignoring finally block output
  • Assuming all repeats run before cancel
  • Missing cancellation catch output
4. Identify the problem in this Kotlin coroutine snippet that tries to handle cancellation:
val job = launch {
    try {
        delay(1000)
    } catch (e: Exception) {
        println("Cancelled")
    }
}
job.cancel()
medium
A. The coroutine never starts because launch is missing parentheses
B. Calling job.cancel() without join causes a deadlock
C. It catches Exception instead of CancellationException, so cancellation is not handled properly
D. delay(1000) cannot be cancelled

Solution

  1. Step 1: Check exception handling

    The catch block catches Exception, which includes CancellationException but does not distinguish it from other exceptions.
  2. Step 2: Understand cancellation propagation

    To specifically handle cancellation without catching unrelated exceptions, catch CancellationException explicitly.
  3. Final Answer:

    It catches Exception instead of CancellationException, so cancellation is not handled properly -> Option C
  4. Quick Check:

    Catch CancellationException explicitly to handle cancellation [OK]
Hint: Catch CancellationException, not just Exception [OK]
Common Mistakes:
  • Assuming Exception catch handles cancellation
  • Thinking delay is uncancellable
  • Confusing cancel() with deadlock
5. You want to cancel a coroutine but still perform some cleanup code without treating cancellation as an error. Which pattern correctly uses CancellationException to achieve this?
hard
A. Avoid catching exceptions and rely on coroutine scope cancellation only
B. Use try-catch with catch (CancellationException) to handle cancellation and run cleanup in finally
C. Use a global exception handler to catch all exceptions including cancellation
D. Use try-catch with catch (Exception) and ignore finally block

Solution

  1. Step 1: Understand cancellation handling best practice

    CancellationException should be caught explicitly to avoid treating cancellation as failure.
  2. Step 2: Use finally block for cleanup

    Cleanup code belongs in finally to ensure it runs whether coroutine completes or is cancelled.
  3. Final Answer:

    Use try-catch with catch (CancellationException) to handle cancellation and run cleanup in finally -> Option B
  4. Quick Check:

    Catch CancellationException and cleanup in finally [OK]
Hint: Catch CancellationException and cleanup in finally block [OK]
Common Mistakes:
  • Catching only Exception hides cancellation
  • Skipping finally block for cleanup
  • Relying on global handlers for cancellation
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