I have a code like this: ```launch { try { myCoroutine() // throws exception when executed ...
d
I have a code like this:
Copy code
launch {
  try {
    myCoroutine() // throws exception when executed
  } catch (e: Exception) {
    println("caught $e")
  }
}
and instead of catching it crashes. But if I replace try/catch with
Copy code
runCatching { myCoroutine() }.exceptionOrNull()?.let { println("caught $e") }
it catches and prints exception. Now,
myCoroutine
above involves calling android-related Retrofit library which has it's own coroutine adapters, so it might be doing some smarty stuff (debugger shows that
continuation.resumeWithException()
is called, maybe on different dispatcher), but I want to understand in general the difference between
try/catch
and `runCatching`: why can this situation happen and when I should use which approach to handling exceptions?
o
are you sure it's not throwing a
Throwable
instead of
Exception
?
runCatching
is literally a
try
-`catch`:
Copy code
public inline fun <R> runCatching(block: () -> R): Result<R> {
    return try {
        Result.success(block())
    } catch (e: Throwable) {
        Result.failure(e)
    }
}
d
hahaha, omg, that's it! I twisted my head in so many ways trying to understand what the hell happens here 🙂
whew, that's good that it turned out to be so stupid. I was afraid that runCatching somehow possesses some magic ways to do a proper catching. Never thought of checking its source, perhaps it would make me doubt that )
m
Just be mindful that when Coroutines get cancelled, a
CancellationException
gets thrown. However it will not cause a crash. If you catch
Throwable
be sure to re-
throw
it if it is an instance of
CancellationException
so that the Coroutine cancels correctly. Otherwise you'll be treating the cancellation as is it were an actual error.
👍 3
d
Thank you!
m
You're welcome 🙂