Kotlin Coroutine — Handling Exceptions
Have you ever worked with an API that always worked as expected and never threw any error? me neither. Since errors are a normal part of any code we write, they are always took in consideration when developing any new technology. Coroutines are no exception.
Different builders, Different behaviors
Coroutine builders have two different categories when propagating errors:
1- Builders that propagate the error automatically : This type of builders including Lunch() and Actor() throws Exceptions directly to be caught be UncaughtExceptionHandler whenever they occurred.
And the result of running this coroutine will be :
2- Builders that propagate errors to be exposed to the users to be consumed finally at the end of the coroutine execution: This type of builders like Async() and produce() wait for the user to consume the result to throw the exception, meaning unless you called await() and receive() on the result we wont see any reported exceptions.
running the previous code wont result in any exception until we decide to get the result from the Deferred object.
And here the exception will be thrown in line 6 the exact time we decide to call await() and then the exception will explode!
Gotta Catch’em All!
Knowing the types of error throwing in coroutines is good but it will be more useful if we know how to handle them.
Exception Handler
Coroutines offers an optional and generic catch block to handle uncaught exceptions called CoroutineExceptionHandler.
Normally, uncaught exceptions can only result from coroutines created using the first type of builders. A coroutine that was created using the second type always catches all its exceptions and represents them in the resulting Deferred object.
Here we passed our AwesomeExceptionHandler to our coroutine launch builder indicating that we want to catch any exceptions with it, resulting in the following :
Note that if you tried CoroutineExceptionHandler registering it in Async coroutine builder and the like of it has no effect.
Plan B: Try-Catch blocks
Since the second type of builders like Async cant be handled using Exception handler, we should be carful that our coroutines don’t swallow an exceptions from type 2 builders, also if we want a very specific error handling logic on some coroutine we relay on using try catch blocks to handle any possible exceptions.
with the following output:
Multiple Coroutines
In case of multiple coroutines the rule is “First Exception Wins”
Meaning the Handler only catches the first exception that accords and causing any other child coroutines to be cancelled.
the fastest error to be throw will be the one caught in the handler before else gets canceled.
Resources
All of the content provided is just a simplified version of :