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.
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:
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:
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
class InvalidNameException(message: String) : Exception(message)
example.kt
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
class InvalidNameException(message: String) : Exception(message)
class InvalidAgeException(message: String) : Exception(message)
example.kt
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:
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.
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)throwsIllegalArgumentExceptionwhen a function argument is invalid.check(condition)throwsIllegalStateExceptionwhen an object or operation is in an invalid state.error(message)throwsIllegalStateExceptionand 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.
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.
TutorialKart.com