Introduction
Custom exceptions in Kotlin allow you to define your own error types that are specific to your application’s requirements. By creating custom exceptions, you can provide more meaningful error messages and handle specific error conditions more gracefully. Custom exceptions are created by extending the Exception
class or any of its subclasses.
Creating Custom Exceptions
To create a custom exception, you need to define a new class that extends the Exception
class or any of its subclasses. You can provide a custom message or additional properties to your exception class.
Syntax
class CustomException(message: String) : Exception(message)
Example
fun main() {
try {
validateAge(15)
} catch (e: InvalidAgeException) {
println("Exception caught: ${e.message}")
}
}
class InvalidAgeException(message: String) : Exception(message)
fun validateAge(age: Int) {
if (age < 18) {
throw InvalidAgeException("Age must be at least 18")
}
}
Explanation:
class InvalidAgeException(message: String) : Exception(message)
: Defines a custom exception classInvalidAgeException
.throw InvalidAgeException("Age must be at least 18")
: Throws the custom exception if the age is less than 18.
Output:
Exception caught: Age must be at least 18
Adding Additional Properties
You can add additional properties to your custom exception class to provide more context about the error.
Example
fun main() {
try {
registerUser("John", "")
} catch (e: InvalidUserException) {
println("Exception caught: ${e.message}, Username: ${e.username}")
}
}
class InvalidUserException(message: String, val username: String) : Exception(message)
fun registerUser(username: String, password: String) {
if (username.isEmpty() || password.isEmpty()) {
throw InvalidUserException("Username and password must not be empty", username)
}
}
Explanation:
class InvalidUserException(message: String, val username: String) : Exception(message)
: Defines a custom exception classInvalidUserException
with an additional propertyusername
.throw InvalidUserException("Username and password must not be empty", username)
: Throws the custom exception if the username or password is empty.
Output:
Exception caught: Username and password must not be empty, Username: John
Custom Exception Hierarchies
You can create a hierarchy of custom exceptions to represent different types of errors in your application.
Example
fun main() {
try {
performTransaction(-100)
} catch (e: TransactionException) {
println("Transaction failed: ${e.message}")
}
}
open class TransactionException(message: String) : Exception(message)
class InsufficientFundsException(message: String) : TransactionException(message)
class InvalidAmountException(message: String) : TransactionException(message)
fun performTransaction(amount: Int) {
if (amount < 0) {
throw InvalidAmountException("Transaction amount must be positive")
}
if (amount > 1000) {
throw InsufficientFundsException("Insufficient funds for transaction")
}
}
Explanation:
open class TransactionException(message: String) : Exception(message)
: Defines a base custom exception classTransactionException
.class InsufficientFundsException(message: String) : TransactionException(message)
: Defines a subclassInsufficientFundsException
.class InvalidAmountException(message: String) : TransactionException(message)
: Defines a subclassInvalidAmountException
.throw InvalidAmountException("Transaction amount must be positive")
: Throws the custom exception if the transaction amount is negative.throw InsufficientFundsException("Insufficient funds for transaction")
: Throws the custom exception if the transaction amount exceeds available funds.
Output:
Transaction failed: Transaction amount must be positive
Using Custom Exceptions in a Project
Here is an example program that demonstrates various aspects of creating and using custom exceptions in Kotlin:
fun main() {
// Using custom exceptions for age validation
try {
validateAge(15)
} catch (e: InvalidAgeException) {
println("Exception caught: ${e.message}")
}
// Using custom exceptions for user registration
try {
registerUser("John", "")
} catch (e: InvalidUserException) {
println("Exception caught: ${e.message}, Username: ${e.username}")
}
// Using custom exceptions for transaction processing
try {
performTransaction(-100)
} catch (e: TransactionException) {
println("Transaction failed: ${e.message}")
}
try {
performTransaction(1500)
} catch (e: TransactionException) {
println("Transaction failed: ${e.message}")
}
}
// Custom exception for age validation
class InvalidAgeException(message: String) : Exception(message)
fun validateAge(age: Int) {
if (age < 18) {
throw InvalidAgeException("Age must be at least 18")
}
}
// Custom exception for user registration
class InvalidUserException(message: String, val username: String) : Exception(message)
fun registerUser(username: String, password: String) {
if (username.isEmpty() || password.isEmpty()) {
throw InvalidUserException("Username and password must not be empty", username)
}
}
// Custom exception hierarchy for transactions
open class TransactionException(message: String) : Exception(message)
class InsufficientFundsException(message: String) : TransactionException(message)
class InvalidAmountException(message: String) : TransactionException(message)
fun performTransaction(amount: Int) {
if (amount < 0) {
throw InvalidAmountException("Transaction amount must be positive")
}
if (amount > 1000) {
throw InsufficientFundsException("Insufficient funds for transaction")
}
}
Output:
Exception caught: Age must be at least 18
Exception caught: Username and password must not be empty, Username: John
Transaction failed: Transaction amount must be positive
Transaction failed: Insufficient funds for transaction
Conclusion
In this chapter, you learned how to create custom exceptions in Kotlin, including how to define custom exception classes, add additional properties, and create custom exception hierarchies. Custom exceptions allow you to provide more meaningful error messages and handle specific error conditions more gracefully, enhancing the robustness and maintainability of your Kotlin applications.