Kotlin Coroutine — Handling Exceptions

Sarah Maher
3 min readSep 22, 2021

--

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.

credits for David Pupaza via Unsplash.com

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.

A simple Exception thrown by lunch builder

And the result of running this coroutine will be :

uncaught as expected !

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.

Error thrown from Async block

running the previous code wont result in any exception until we decide to get the result from the Deferred object.

Representation of calling await here

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.

Exception Handler in action

Here we passed our AwesomeExceptionHandler to our coroutine launch builder indicating that we want to catch any exceptions with it, resulting in the following :

caught it like a boss!

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:

caught like a boss once again!

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.

And the winner is Arithmetic Exception!!

Resources

All of the content provided is just a simplified version of :

--

--

Sarah Maher

An Engineer Who Keeps talking about Android || Women In Tech || Find me on LinkedIn : https://www.linkedin.com/in/sarah-maher-awad/