https://kotlinlang.org logo
Title
m

Mark

01/13/2021, 2:31 AM
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
.
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

muliyul

01/13/2021, 2:47 AM
Change the name so it will hint it should be used inside coroutines
inline fun safeCoTry(block: () -> Unit) { 
    try {
        block()
    } catch (e: Exception) {
        if(e is CancellationException) // propogate
         throw e
        println(e.toString())
    }
}
m

Mark

01/13/2021, 2:48 AM
Yes, I know how to rethrow it. It’s just that there are many inline functions (already defined) that know nothing about coroutines.
m

muliyul

01/13/2021, 2:50 AM
from std lib or your own?
m

Mark

01/13/2021, 2:51 AM
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

muliyul

01/13/2021, 2:53 AM
I don't think you have many options tbh.
m

Mark

01/13/2021, 2:58 AM
Perhaps there should be a lint check for when an inline function catches
Exception
thrown from lambda argument.
e

ephemient

01/13/2021, 3:02 AM
catching unknown exceptions without rethrowing them seems problematic in general, not just in this case
1
m

Mark

01/13/2021, 3:07 AM
CancelletionException
seems like a very different type of exception that perhaps deserves its own category, much like how
Error
is treated differently.
e

ephemient

01/13/2021, 5:09 AM
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

Mark

01/13/2021, 5:14 AM
It’s more the existence of inline higher order functions that makes this more of an issue.
a

Adam Powell

01/13/2021, 5:35 PM
IllegalStateException
in general (which
CancellationException
extends) tends to indicate something that shouldn't wrap/log and continue.
👍 1