🎓 A1Learner
🔍
0 of 37 lessons completed

Kotlin Custom Exceptions

A custom exception is an exception class written for one kind of problem in a program. Code throws it when that problem happens and a catch block reads its message.

Throwing and catching a custom exception

checkName throws EmptyNameException for an empty name. The catch block prints the message stored in the exception.

class EmptyNameException(message: String) : Exception(message)

fun checkName(name: String) {
    if (name.isEmpty()) {
        throw EmptyNameException("Name is empty")
    }
    println(name)
}

fun main() {
    try {
        checkName("")
    } catch (e: EmptyNameException) {
        println(e.message)
    }
    checkName("Maya")
}

An exception with an error code

LimitException carries a code property beside its message. The catch block prints both stored values.

class LimitException(message: String, val code: Int) : Exception(message)

fun addScore(score: Int) {
    if (score > 100) {
        throw LimitException("Score too high", 41)
    }
    println(score)
}

fun main() {
    try {
        addScore(140)
    } catch (e: LimitException) {
        println(e.message)
        println(e.code)
    }
}

Two related exceptions caught separately

A low score throws TooSmallException and a high score throws TooLargeException. Each try block lists a catch block for both types.

class TooSmallException(message: String) : Exception(message)

class TooLargeException(message: String) : Exception(message)

fun grade(score: Int) {
    if (score < 0) {
        throw TooSmallException("Score below zero")
    }
    if (score > 100) {
        throw TooLargeException("Score above limit")
    }
    println(score)
}

fun main() {
    try {
        grade(-3)
    } catch (e: TooSmallException) {
        println(e.message)
    } catch (e: TooLargeException) {
        println(e.message)
    }
    try {
        grade(150)
    } catch (e: TooSmallException) {
        println(e.message)
    } catch (e: TooLargeException) {
        println(e.message)
    }
}

A class that guards its own values

The init block of Person throws AgeException for a negative age. The valid person prints before the failing one is tried.

class AgeException(message: String) : Exception(message)

class Person(val name: String, val age: Int) {
    init {
        if (age < 0) {
            throw AgeException("Age cannot be negative")
        }
    }
}

fun main() {
    val ok = Person("Ana", 20)
    println(ok.age)
    try {
        val bad = Person("Bo", -1)
        println(bad.age)
    } catch (e: AgeException) {
        println(e.message)
    }
}

Example

class MissingItemException(message: String, val item: String) : Exception(message)

fun findItem(items: List<String>, wanted: String): String {
    for (item in items) {
        if (item == wanted) {
            return item
        }
    }
    throw MissingItemException("Item not found", wanted)
}

fun main() {
    val shelf = listOf("pen", "book", "cup")
    println(findItem(shelf, "book"))
    try {
        println(findItem(shelf, "lamp"))
    } catch (e: MissingItemException) {
        println(e.message)
        println(e.item)
    }
}

Key points

  • A custom exception class extends Exception and passes a message to it.
  • The throw statement raises an exception object at the point of a problem.
  • A catch block for the custom type runs when that exception is thrown.
  • The message property of the caught exception holds the text passed at the throw.
  • A custom exception can carry extra properties beside its message.
  • Related problems can use separate exception classes and separate catch blocks.

In this example, findItem returns the wanted word when the shelf holds it. The shelf holds book, so the first call prints book. The shelf has no lamp, so the second call throws MissingItemException and the catch block prints its message and its stored item.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Kotlin Playground

Exercise

What does println(e.message) print inside a catch block for an exception thrown with the text "Door locked"?