Kotlin programming language
Kotlin programming language
Exceptions

Kotlin programming language

What? Why?

An exception signals that something went exceptionally wrong

  • Development mistakes
  • Errors produced by external (to the program) resources
  • System errors

Why use exceptions:

  • To separate error-handling code from regular code
  • To propagate errors up the call stack – maybe someone knows how to deal with the error
  • To group and differentiate error types

Do NOT use exceptions for:

  • Control flow
  • Manageable errors
Kotlin programming language

How?

fun main() {
   throw Exception("Hello, world!")
}

Or even better:

fun main() {
   val nullableString: String? = null
   println("Hello, NPE! ${nullableString!!}")
}
Exception in thread "main" java.lang.NullPointerException
Kotlin programming language

Example

fun main() {
    try {
        throw Exception("An exception", RuntimeException("A cause"))
    } catch (e: Exception) {
        println("Message: ${e.message}")
        println("Cause: ${e.cause}")
        println("Exception: $e") // e.toString() is called
        e.printStackTrace()
    } finally {
        println("Finally always executes")
    }
}
Kotlin programming language

Example #2

data class Person(val name: String, val surname: String, val age: Int) {
    init {
        if (age < 0) {
            throw IllegalStateException("Age cannot be negative")
        }
        if (name.isEmpty() || surname.isEmpty()) {
            throw IllegalArgumentException("For blank names/surnames use -")
        }
    }
}
Kotlin programming language

Dealing with exceptions

try {
    val (n, s, a) = readLine()!!.split('/')
    val person = Person(n, s, a.toInt())
    addToDataBase(person)
} catch (e: IllegalStateException) {
    println("You've entered a negative age! Why?")
} catch (e: IllegalArgumentException) {
    println(e.message)
} catch (e: NullPointerException) {
    println("NPE ;^)")
} catch (e: Exception) {
    println("Something else went wrong")
    throw Exception("Failed to add to the database", e)
} finally {
    println("See you in the next episodes!")                                                        .
}

You might:

  • Handle the error properly and continue execution
  • Handle something on your side and re-throw the exception
Kotlin programming language

Taxonomy

open class Throwable + open val message: String? + open val cause: Throwable? + fun getStackTrace(): Array<String> + fun printStackTrace() + open fun toString(): String open class Error : Throwable open class Exception : Throwable open class AssertionError : Error class NotImplementedError : Error open class OutOfMemoryError : Error open class RuntimeException : Exception class ArithmeticException : RuntimeException open class CharacterCodingException : Exception class ForeignException : Exception class IllegalCallableAccessException : Exception class IllegalPropertyDelegateAccessException : Exception class NoSuchPropertyException : Exception
Kotlin programming language

Kotlin sugar

try is an expression:

val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }

More sugar:

require(count >= 0) { "Count must be non-negative, was $count" } 
// IllegalArgumentException

error("Error message") 
// IllegalStateException
Kotlin programming language

Thanx!

Throwable

Error

Exception

Error subclasses

RuntimeException

ArithmeticException

Right column: direct Exception subclasses

ARROWS

Error -> Throwable

AssertionError -> Error

RuntimeException -> Exception

Direct Exception subclasses -> Exception (routed via vertical spine at x=790)