Why does the below logic crashes where as if i separate the top-level it doesn't.
val toplevel = CoroutineScope(Dispatchers.IO)
this crashes:
toplevel.launch {
val sync = async {
print("this is sync 1")
throw RuntimeException()
}
try {
sync.await()
} catch (e: Exception) {
print("Exception handled")
}
}
This does not:
val sync = toplevel.async {
print("this is sync 1")
throw RuntimeException()
}
toplevel.launch
try {
sync.await()
} catch (e: Exception) {
print("Exception handled")
}
}
s
Sam
08/24/2022, 9:18 AM
Because when
async
fails it also causes its parent job to fail
Sam
08/24/2022, 9:20 AM
In your first example, the parent of
async
is the
launch
job, so when the
async
job fails, the
launch
job fails too. It might never reach the
catch
because the job could fail before it got there.
Sam
08/24/2022, 9:21 AM
In the second example, the
async
job has no parent job so the failure doesn’t propagate anywhere until you call
await()
.
v
Vikas Singh
08/24/2022, 9:55 AM
If i surround async with try catch it should be able to handle it right ? for the first case where parent is launch
s
Sam
08/24/2022, 10:28 AM
No, because the error isn’t thrown when you call
async
. The call to
async
just starts the job and then returns immediately. The error happens later, in the background, and propagates directly to the parent job.