As I mentioned in my previous article, Kotlin Coroutine 101, it introduces the scope of “Structured Coroutine”. Within the same CoroutineScope, if one of the jobs throws an exception, it will propagate to the top and the rest of jobs will be cancelled to prevent memory leaks.
In this article, I will talk about the exception aggregation in Kotlin Coroutine and how we can handle exceptions better than before with it.
Traditionally, when we need to deal with exceptions, we can simply use try…catch… to wrap up the risky logic. And we will deal the exceptional cases in the catch block.
Similar to the case where there are multiple types of exceptions to handle.

In the above case, it works fine because each suspend function execute in a sequential order. How about in a concurrent order?
If you run it here, you will notice it fails hard and blow up the program. In other words, the catch block does not do the job in this case.
If we move the first launch inside the try block, we can fix the issue. But such nuance change is not trivial, so can we do better?
In Kotlin Coroutine, we have CoroutineExceptionHandler designed for such case. Basically, it servers a catch block in coroutine for custom to handle exceptions.
And when the exceptions propagates to the top, it will catch them in one place.
In the concurrent execution case, we can still use the same handler but it leaves a few boilerplate in the trace. And it’s not nice.
Alternatively, we can define our own CoroutineScope with the handler.
An interesting thing happens here if you run the code. You will notice the three functions are triggered but only one exception has been logged.
Why?
If you remember the “Structured Coroutine” in the previous article, you’d notice it’s because the child job’s failure triggers the parent to cancel the rest of children jobs.
Can we still print out all other exceptions? Here comes the SupervisorJob.
In this example, since we have used SupervisorJob, the cancellation propagation mechanism becomes only downwards. In other words, if a child fails, it will not trigger the scope to cancel the rest; but if the scope is cancelled, all children will be cancelled.
In summary, when handling exceptions in Kotlin Coroutine, we’d better leverage its CoroutineExceptionHandle api so that we can take advantage of its exception propagation pattern and supervised coroutineScope.
