Kotlin Custom Exceptions

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 class InvalidAgeException.
  • 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 class InvalidUserException with an additional property username.
  • 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 class TransactionException.
  • class InsufficientFundsException(message: String) : TransactionException(message): Defines a subclass InsufficientFundsException.
  • class InvalidAmountException(message: String) : TransactionException(message): Defines a subclass InvalidAmountException.
  • 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top