Create a Custom Exception in Kotlin

A custom exception represents an application-specific error, such as an invalid name, an unsupported account state, or a business-rule violation. In Kotlin, create one by defining a class that extends Exception or another suitable exception type.

Custom exception types make failures easier to identify and handle. A catch block can respond to the specific application error without treating every failure as a generic Exception.

Message, cause, and stack trace in a Kotlin exception

An exception can provide the following diagnostic information:

  • Message: A readable description of the failure, available through message.
  • Cause: The underlying exception that produced the current failure, available through cause.
  • Stack trace: The sequence of calls active when the exception was created.

Preserving the cause is particularly useful when converting a low-level exception into a domain-specific exception.

Syntax for a Kotlin custom exception

The custom exception class extends Exception and passes its message to the superclass constructor.

</>
Copy
class CustomExceptionName(message: String) : Exception(message)

Kotlin does not have Java-style checked exceptions. A function may throw an exception without declaring it in its signature, so callers need clear documentation when a failure is expected and recoverable.

Kotlin custom exception with message and cause

A reusable exception can accept both a message and an optional cause:

</>
Copy
class DataImportException(
    message: String,
    cause: Throwable? = null
) : Exception(message, cause)

When another exception is caught and translated, pass it as the cause instead of discarding it:

</>
Copy
fun importNumber(value: String): Int {
    try {
        return value.toInt()
    } catch (e: NumberFormatException) {
        throw DataImportException("Cannot import '$value' as an integer.", e)
    }
}

Example 1: Throw and catch InvalidNameException

This example defines InvalidNameException and throws it when a name contains a numeral. The specific catch block appears before the general Exception catch block.

custon_exception.kt

</>
Copy
class InvalidNameException(message: String) : Exception(message)

example.kt

</>
Copy
fun main(args: Array<String>) {

    var name = "Tutorial 60"

    try {
        validateName(name)
    } catch (e : InvalidNameException){
        println(e.message)
    } catch (e : Exception){
        println(e.message)
    }

}

fun validateName(name : String){
    if(name.matches(Regex(".*\\d+.*"))) {
        throw InvalidNameException("Your name : $name : contains numerals.")
    }
}

Output

Your name : Tutorial 60 : contains numerals.

Example 2: Define multiple Kotlin custom exceptions

A Kotlin file can contain multiple classes. The following example defines separate exception types for invalid names and invalid ages, allowing callers to handle the two validation failures independently.

custom_exception.kt

</>
Copy
class InvalidNameException(message: String) : Exception(message)

class InvalidAgeException(message: String) : Exception(message)

example.kt

</>
Copy
fun main(args: Array<String>) {

    var name = "Tutorial 60"
    var age = 2

    try {
        validateName(name)
    } catch (e : InvalidNameException){
        println(e.message)
    } catch (e : InvalidAgeException){
        println(e.message)
    }

    try {
        validateAge(age)
    } catch (e : InvalidNameException){
        println(e.message)
    } catch (e : InvalidAgeException){
        println(e.message)
    }

}

fun validateName(name : String){
    if(name.matches(Regex(".*\\d+.*"))) {
        throw InvalidNameException("Your name : $name : contains numerals.")
    }
}

fun validateAge(age : Int){
    if(age <18 || age > 100) {
        throw InvalidNameException("Your age $age did not meet the criteria.")
    }
}

Output

Your name : Tutorial 60 : contains numerals.
Your age 2 did not meet the criteria.

In the preceding code, validateAge() throws InvalidNameException. That produces the displayed output, but the exception type does not match the age validation error. The corrected function should throw InvalidAgeException:

</>
Copy
fun validateAge(age: Int) {
    if (age < 18 || age > 100) {
        throw InvalidAgeException("Your age $age did not meet the criteria.")
    }
}

Catch multiple Kotlin exception types correctly

Kotlin uses separate catch blocks when different exception types require different handling. Place a more specific exception before a broader superclass; otherwise, the broader block can make the specific block unreachable.

</>
Copy
try {
    validateName("Tutorial 60")
} catch (e: InvalidNameException) {
    println("Invalid name: ${e.message}")
} catch (e: IllegalArgumentException) {
    println("Invalid argument: ${e.message}")
} catch (e: Exception) {
    println("Unexpected failure: ${e.message}")
}

If several exception types receive exactly the same treatment, a single catch (e: Exception) block is possible, but it loses type-specific handling. Avoid catching Throwable for ordinary application errors because it also includes serious JVM errors.

Use require, check, or a custom exception in Kotlin

Kotlin provides standard validation functions for common programming errors:

  • require(condition) throws IllegalArgumentException when a function argument is invalid.
  • check(condition) throws IllegalStateException when an object or operation is in an invalid state.
  • error(message) throws IllegalStateException and is useful for a branch that should not be reached.
  • A custom exception is appropriate when callers need to distinguish a domain-specific failure by its type or retain structured details about it.

The exception thrown by require cannot be replaced with a custom type. Use an explicit condition and throw when a custom exception is required.

</>
Copy
class InvalidOrderException(message: String) : Exception(message)

fun validateQuantity(quantity: Int) {
    if (quantity <= 0) {
        throw InvalidOrderException("Quantity must be greater than zero.")
    }
}

Custom exception or sealed result type

Use an exception for a failure that interrupts normal execution, especially when it may need to travel through several call levels. For an expected outcome that callers routinely inspect, a nullable value, Result, or a sealed result type may make the control flow clearer. The choice depends on whether the condition is exceptional or part of the normal function contract.

Kotlin custom exception FAQ

How do I create a custom exception in Kotlin?

Define a class that extends Exception, pass a message to the superclass constructor, and create the exception with throw. For example: class InvalidValueException(message: String) : Exception(message).

Can a Kotlin custom exception store additional data?

Yes. Add constructor properties that describe the failure, such as an invalid value or record identifier. Do not include passwords, tokens, or other sensitive values in exception messages or logged properties.

Are custom exceptions checked exceptions in Kotlin?

No. Kotlin treats exceptions as unchecked. A function does not need a throws declaration, and callers are not forced by the compiler to catch the exception.

How do I preserve the original cause of a Kotlin exception?

Accept a nullable Throwable in the custom exception constructor and pass it to Exception(message, cause). When translating a caught exception, supply that caught exception as the cause.

Can require throw a custom exception in Kotlin?

No. require throws IllegalArgumentException. To throw a custom exception, write an if condition followed by an explicit throw CustomException(...).

Kotlin custom exception editorial QA checklist

  • Confirm that each custom exception name describes the failure it represents.
  • Verify that every validation function throws the matching exception type.
  • Place specific catch blocks before broader exception handlers.
  • Preserve the original cause when wrapping a lower-level exception.
  • Check that exception messages explain the failure without exposing sensitive data.

Summary of Kotlin custom exceptions

A Kotlin custom exception is a class derived from Exception or another appropriate exception type. Give it a specific name, include a useful message, preserve the underlying cause when wrapping another failure, and catch it only where the program can respond meaningfully. Continue with the Kotlin Tutorial for related Kotlin language examples.