PHondogo
06/18/2024, 9:49 PMPHondogo
06/18/2024, 9:50 PM// 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
}
Sam
06/19/2024, 7:12 AMCancellationException
.PHondogo
06/19/2024, 8:33 AMtry {
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
}
}
PHondogo
06/19/2024, 8:36 AMSam
06/19/2024, 9:00 AMthrow 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 😞.