Hey folks, recently i bumped into a problem of `M...
# coroutines
a
Hey folks, recently i bumped into a problem of
MonoCoroutine was cancelled
. Now i get it that when a coroutine is cancelled and we await, it will throw this JobCancellationExeception. For this i have done a standard try/catch method where i catch a CancellationException and it does not rethrow it. Now there are several reads i had over this topic. I want to have a public opinion on what are the best practices to handle this. Here is a code snippet:
Copy code
val coroutineScope = CoroutineScope(<http://Dispatchers.IO|Dispatchers.IO>)
...
suspend func1() = withContext(coroutineScope.context) {
    val deferredJob1 = async { someFunctionWhichCanThrowException() } // consider this throws an exception
    val deferredJob2 = async { someFunction2WhichCanThrowException() }
    val job1 = job1.await()   // this will then throw a JobCancellationException
    val job2 = job2.await()
}
...
now this await() i replaced it with
safeAwait()
which is basically a try/catch block. My use case also have an awaitAll(), for which i have used
.map{ safeAwait() }
(ik its not optimised) thats why i wanna ask for a public opinion on whats the best practice to follow here?
s
In your example, the exception from
deferredJob1
will propagate to the scope and cause the
withContext
block to fail with the same exception. If you do reach the call to
job1.await()
, any cancellation exception it throws will be ignored and the original exception is the one that will be thrown.
Can you make a runnable example which demonstrates the exact problem you're running into?
a
@Sam well, this was an runnable example, weird that when i wrote the UTs for it as you said the original exception was thrown indeed, however, would the behavior change if the someFunctionWhichCanThrowException() is also a suspend cancellable function?
well, here is another example:
Copy code
suspend fun func1() = mono { someAPI() }
suspend fun func2() = mono { 
    ...
    val job1 = func1.awaitSingle() // job cancellation exception
    return ...
}
i think a much more decent way to handle this would be SupervisorJob() other than wrapping the safe try/catch everywhere?
👌 1
💯 1
a
Yes, SupervisorJob would be best for your scenario, supervisorJob will allow other child's job to be completed even if any other child has thrown exception, but in other case if any child routine throws exception it will stop other child's coroutines as well which is happening in your case. sharing article for more detail https://amitshekhar.me/blog/coroutinescope-vs-supervisorscope
457 Views