DEV Community

RockAndNull
RockAndNull

Posted on • Originally published at rockandnull.com on

Error hierarchies and Kotlin sealed interfaces

Error hieranchies and Kotlin sealed interfaces

In a previous post, I covered what I consider a pretty useful feature of Kotlin: sealed classes.

These classes can be quite useful when modeling errors in Android apps (and beyond). But they have their limitations. Classes, as you probably know, in Kotlin can only extend a single class. What happens, in the relatively common scenario, where an error belongs to multiple error "categories"?

Enter sealed interfaces. A class can implement multiple interfaces. So if the error "categories" are defined as sealed interfaces, a concreate error can belong to multiple "categories".

sealed interface ExpectedError
sealed interface UserError

data class InvalidUserError(val id: Int): UserError, ExpectedError // 1.
data class InvalidArgumentError(val message: String): ExpectedError

fun handleUserError(error: UserError) { // 2.
    TODO() 
}

fun handleExpectedError(error:ExpectedError) { // 3.
    when(error) {
        is InvalidArgumentError -> TODO()
        is InvalidUserError -> TODO()
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. A single error can belong to multiple "categories".
  2. And you can handle the error "category" as a whole or ...
  3. ... handle each error specifically using the when statement.

But what's the benefit over defining a normal interface? Remember that you can define subclasses of sealed classes and interfaces only in the same Kotlin module. This limits the scope where these hierarchies can be extended (i.e. in the same module) and therefore limits the misuse surface.

Although this might seem like a simple feature, it opens the way for defining comprehensive error hierarchies. Hopefully, you can use it to make your codebase a bit tidier and a bit harder to misuse.

Happy coding!

Top comments (0)