How to avoid accidentally catching `CancellationEx...
# coroutines
m
How to avoid accidentally catching
CancellationException
? For example, any inline (not suspending) higher order function could innocently be catching
Exception
and converting to some sealed class. It knows nothing about coroutines and so would have no reason to give special treatment to
CancellationException
.
Copy code
fun main() {
    runBlocking {
        val job = launch {
            test {
			    delay(1000L)
                println("finished long delay")
            }
            println("finished test")
        }
        delay(100L)
        job.cancel()
    }
}

inline fun test(block: () -> Unit) {
    try {
        block()
    } catch (e: Exception) {
        println(e.toString())
    }
}

// kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job="coroutine#2":StandaloneCoroutine{Cancelling}@de0a01f
// finished test
m
Change the name so it will hint it should be used inside coroutines
Copy code
inline fun safeCoTry(block: () -> Unit) { 
    try {
        block()
    } catch (e: Exception) {
        if(e is CancellationException) // propogate
         throw e
        println(e.toString())
    }
}
m
Yes, I know how to rethrow it. It’s just that there are many inline functions (already defined) that know nothing about coroutines.
m
from std lib or your own?
m
Internal shared code. So yes, I could just introduce coroutine dependency everywhere, but this doesn’t seem good to me. Regardless, also potentially an issue with 3rd party non-coroutine libraries.
m
I don't think you have many options tbh.
m
Perhaps there should be a lint check for when an inline function catches
Exception
thrown from lambda argument.
e
catching unknown exceptions without rethrowing them seems problematic in general, not just in this case
1
m
CancelletionException
seems like a very different type of exception that perhaps deserves its own category, much like how
Error
is treated differently.
e
for what it's worth, Java's InterruptedException is similar: used for Thread.interrupt(), should not be ignored, and extends Exception, not Error
👍 1
m
It’s more the existence of inline higher order functions that makes this more of an issue.
a
IllegalStateException
in general (which
CancellationException
extends) tends to indicate something that shouldn't wrap/log and continue.
👍 1
173 Views