Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Throwing Exceptions

To signal an error from your own code, you must create an exception object and then throw it. Kotlin allows you do to this directly, via the throw statement, or indirectly, using one of its precondition functions.

Direct Use of throw

Consider the variance() function discussed earlier. Instead of returning -1.0 to signal an error, you could do this instead:

fun variance(dataset: List<Double>): Double {
    if (dataset.size < 2) {
        throw IllegalArgumentException("not enough data")
    }
    ...
}

Important

Remember that exceptions change flow of control completely. No other part of the variance() function will execute once the exception is thrown.

Remember that flow of control will be affected in the code that called variance(), too.

Precondition Functions

You can also throw certain exceptions using the functions require(), check() and error(). These typically require a little less code than throwing the exception directly yourself, but their main benefit is that they can make the intention of your code clearer.

require() will throw IllegalArgumentException if the boolean expression specified as its first argument evaluates to false. The message associated with the exception is provided by an optional second argument, which is a lambda expression.

For example, the error handling for variance() could be written like this:

fun variance(dataset: List<Double>): Double {
    require(dataset.size > 1) { "not enough data" }
    ...
}

Notice how clear and readable this is.

check() will throw an IllegalStateException if the boolean expression supplied as its first argument evaluates to false. The message associated with the exception is provided by an optional second argument which is, again, a lambda expression.

error() is the simplest of the three functions. It takes an error message as its sole argument and throws an IllegalStateException with that message.

Tip

require() is a neat way of verifying the prerequisites needed for a successful function call, before any further computation is attempted, whereas check() is intended for use later on in a function’s code, for the purpose of checking whether computation is proceeding as expected.

Together, these two functions fulfil a similar role to assert statements in C & Python.