What is the best way to check by CancellationExcep...
# coroutines
p
What is the best way to check by CancellationException that coroutine was cancelled without Exception? Now I'm using such logic (in thread):
Copy code
// if cause is null then it is non exceptional cancellation
fun getCancellationExceptionCause(e: CancellationException): Throwable? {
    val causes = HashSet<Throwable>()
    var cause = e.cause
    while (cause != null) {
        if (cause !is CancellationException) {
            return cause
        }
        if (!causes.add(cause)) {
            break
        }
        cause = cause.cause
    }
    return null
}
s
Can you say more about what you mean? If the coroutine failed, I'd expect you would see a different exception, not a
CancellationException
.
p
Please consider this code:
Copy code
try {
    coroutineScope {
        //cancel() // normal cancel
        cancel(cause = CancellationException(Exception("test"))) // exceptional case
    }
} catch (e: CancellationException) {
    val cause = getCancellationExceptionCause(e) // fun from previous message
    if (cause != null) {
        throw cause
    }
}
In case of not catching like this normal cancellation propagated out of coroutineScope
s
I'm not sure I agree with the distinction between "exceptional" and "normal" in your example. A cancellation is always a normal termination. The 'cause' is just there for informational or debugging purposes. If you have a failure, you should just
throw Exception("test")
instead of calling
cancel()
. As an aside, calling
cancel()
inside a
coroutineScope
to cancel the current coroutine introduces a new problem of its own, so there's more going on here than a simple cancellation. That's because
coroutineScope
returns a result. Attempting to retrieve a result from a cancelled coroutine will raise a new cancellation exception, which is not normally a good thing 😞.
🙏 1
☝️ 1