How Kotlin can help us with error handling

The announcement made on this year’s Google I/O ’17 that Kotlin is now an officially supported language for Android development caught some of us by surprise. There are several differences between Kotlin and the plain old Java and thus it’s important that we have a good grasp on how we can solve old problems on different better ways. The idea here is not to dissect the language by any means, but instead to have a glimpse on how it’s rich, expressive and fulfilled of interesting mechanics even on what regards error handling on a cleaner way.

As with Java, where everything is a subclass of Object, on Kotlin the root of all classes is the type Any. The news here is that in Kotlin we also have the Nothing class, which in turn is by itself a subclass of all the classes. This is how it’s all wrapped up:

It’s purpose is very nicely explained by Lorenzo Quiroli on his post Nothing (else) matters in Kotlin and I do recommend that you read it if you haven’t already. Therefore, my intention here is simply to show how we can make use of the Nothing type in order to fail, so to speak, in a gracefully manner.

The use case

Let’s start from an hypothetical situation where we want to output a given user’s name. We know that this name is a property from a Userobject which we can have access to or not. Let’s also suppose that the result of outputting this user’s name is of the essence for our use case or else we should straightly through an exception. This is how we would do it:

Note that the getUser()function returns the type User? which means that it can return an object of the type User or null.

Next we check for the returned User object. In case it’s not null show it, otherwise throw an exception and we’re good.

But hey, it’s Kotlin! Shouldn’t we be less verbose?

Sure we can. Let’s start by pruning all those nasty explicit null-checks:

Much better now with the elvis operator in place (the little guy with a quiff: ?:) — no ifs, no braces and a couple of lines of code. But what does this elvis operator guy do? Well, roughly speaking, if the getUser() function returns a value other than null, then it will be assigned, otherwise the expression say that we should throw an exception. Neat. But what if we want a varying error message to be shown accordingly to the failure that effectively happened?

Making it general

Let’s handle our error in a more general way. A good starting point is to decouple the fail handler to a separate function:

Well, that’s just fine and dandy, huh? The problem is the code above won’t compile. Why, you might be asking now. We have a type mismatch error there because the value user expects an object of type User but the fail function returns a type Unit(the voidequivalent from Java).

Remembering that every function declared in Kotlin without an explicit return type will implicitly return Unit, as with the fail function above. Making it clear:

So how to solve it in order to make the compiler happy?

Well, it’s just a matter of declaring Nothing as the return type of fail as follows:

Remember we said that the Nothing type is a subclass of all other classes? Well, then, because of this, the return type of the fail function in the snippet above is inferred by the compiler as being the type User.

Should the getUser() function above return null, the output we’ll have is something similar to this:

Exception in thread “main” java.lang.IllegalStateException: User not found!
at com.mycompany.MainTestKt.fail(MainTest.kt:13)
at com.mycompany.MainTestKt.main(MainTest.kt:4)

Nice. But why does it work now?

Remember we said that the Nothing type is a subclass of all other classes? Well, then, because of this, the return type of the fail function in the snippet above is inferred by the compiler as being the type User.

Should the getUser() function above return null, the output we’ll have is something similar to this:

Exception in thread “main” java.lang.IllegalStateException: User not found!
at com.mycompany.MainTestKt.fail(MainTest.kt:13)
at com.mycompany.MainTestKt.main(MainTest.kt:4)

It’s getting better and also with a plus on self-documenting code. A function that returns Nothing indicates that the execution won’t go beyond that point.

Suppressing the stacktrace

What if we want to output only the error message without the stacktrace? Normally, suppressing the stacktrace is undesirable since we would lose valuable input to assist us on keep tracking of the error. It makes sense but, maybe that’s what we want, why not? Nothing more than that, just raise the exception and exit with an error code. Maybe you don’t feel its usefulness but I did it on a pet project I was working on, which consists of a command line tool. The way I did this was by implementing the Thread.UncaughtExceptionHandler

The Java Thread class method setDefaultUncaughtExceptionHandler takes as its sole argument an implementation of theThread.UncaughtExceptionHandler interface. This type of interface with a single method has a special name on Java 8 — SAM (or Single Abstract Method interface). As with Java 8, in Kotlin, functions that take SAM interfaces can be replaced by lambdas, as long as they have the same method signature as the single abstract method of the interface declared in Java. This interface declared in Java:

Therefore, we can refer to them using Kotlin lambdas:

Thread.setDefaultUncaughtExceptionHandler({ t, e -> // ... })

It happens that in Kotlin, when we have functions that take lambdas as its last or sole argument we can declare the lambda’s body outside of the parenthesis:

Thread.setDefaultUncaughtExceptionHandler() { t, e -> // ... }

In addition to that, note that the lambda function is the only parameter of the method so we can completely omit the parenthesis from the declaration:

Thread.setDefaultUncaughtExceptionHandler { t, e -> // ... }

Much better, huh? Stepping back to our example, any line of code afterwards a call to the fail function will not be executed, the program exits and the output we get in case getUser() returns null will be just a plain message:

No user found!

As we can see, Kotlin has a whole bunch of syntactic sugars and functional constructs that we observe on by-design functional languages and wrapping up we have access to a powerful toolset to assist us on reducing to a minimal though expressive necessary codebase. In other words, we can now focus on the problem itself which is what really matters.

Hooray! Does it mean that we can now abandon Java for good?

Well, It’s a matter of choice, just don’t follow the hype solely for the hype. If you ask me though, I would answer that it depends. In fact, Java has its limitations on its own but we should not forget that Java is the foundation of all the other languages that runs upon the JVM and it keeps evolving on its own steps following a concern regarding backwards compatibility. On that account I think that it’s important for anyone who doesn’t have a reasonable solid base on what happens behind the curtains when it comes to programming with Java, to stick with it. Doing everything on Java’s plain old explicit and bureaucratic form can be a very resourceful learning path. When the time comes, then you can make your own parallel and hence make the best choice for your case, understanding where in fact, you’re winning with it.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.