Here if `unsafeMethod` fails it will make the pare...
# coroutines
j
Here if
unsafeMethod
fails it will make the parent job fail, which basically mean a crash of the UI componenent (any working coroutine will be cancelled and further action would no longer work) Of course I could encapsulate the call in
try-catch
. But it is a bit boilerplate and easy to forget. (here it is obvious, but what about unexpected exceptions?) How could I launch a child coroutine in a way that it does'nt propagate the failure to the parent?
p
using try-catch inside your child coroutine for unsafe block...
j
But what about "unexpected exception"? Should I put try-catch block everywhere for each function? This is a lot of boilerplate code which is btw easy to forget.
p
Think you should log your unexpected exceptions using some UncaightException Handler and investigate it
j
Of course exception are logged using the default
UncaughtExceptionHandler
.
p
or try/catch every block in development stage if you unsure
j
But I still want to make sure that the UI doesn't crash
even if an error has been logged and displayed to the user
or try/catch every block in development stage if you unsure
That's what I want to avoid. And what about production? It is even more true for production code. I don't want the UI to crash in production either, do I?
p
It’s philosophical issue. If you have some components that cannot be relied on your implementation, i.e NetworkRequests, try-catch it, then user clicks on JButton , it should not crash your app
j
Yes that's for expected exception. I have no problem with that. If a function is unsafe, then it is encapsulated in a
try-catch
and exception are managed.
But I want my UI to be safe to all exceptions. expected and unexpected ones. expected ones are managed by
try-catch
blocks and unexpected are logged and displayed to the user using an
UncaughtExceptionHandler
. But still I'd like that the UI remains usable, even after unexpected exceptions.
Here is a work-around:
Copy code
abstract class ExceptionSafeCoroutineScope(private val dispatcher: CoroutineDispatcher) : CoroutineScope {
  private var job = Job()

  private val exceptionHandler = CoroutineExceptionHandler { _, exception ->
    Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), exception)
    job = Job()
  }

  final override val coroutineContext: CoroutineContext
    get() = job + dispatcher + exceptionHandler
}
But I wonder what is the recommended way of doing it.
k
if you don’t want the coroutine you launch to be a child of the current scope and everything that implies (i.e. cancellation), then maybe it’s a candidate to be launched in another scope:
GlobalScope.launch { ... }
j
Yes, but I want it to be a child. I still want all children to be cancelled at the end of life of the UI component.
e
I think I understand what you need. We’ve been thinking about this feature for a while. Here I wrote it down: https://github.com/Kotlin/kotlinx.coroutines/issues/576
👍 2
j
Thank you @elizarov!