❗ Kotlin – Custom Exceptions: Define Your Own Error Types
🧲 Introduction – Why Learn Kotlin Custom Exceptions?
While Kotlin provides standard exceptions like IllegalArgumentException, sometimes you need to represent domain-specific error scenarios. That’s where custom exceptions come in—they help you create semantic, reusable, and testable error-handling logic tailored to your app’s needs.
🎯 In this guide, you’ll learn:
- How to create and use custom exceptions
- When to prefer a custom exception over built-in ones
- How to inherit from the right base class (Exception,RuntimeException)
- Best practices and real-world use cases
🔧 Defining a Simple Custom Exception
class InvalidUserInputException(message: String) : Exception(message)
✔️ This class inherits from Kotlin’s standard Exception class and can carry a custom message.
🧪 Throwing Your Custom Exception
fun validateUsername(username: String) {
    if (username.isBlank()) {
        throw InvalidUserInputException("Username must not be blank")
    }
}
🔹 Usage:
try {
    validateUsername("  ")
} catch (e: InvalidUserInputException) {
    println("Caught: ${e.message}")
}
🟢 Output:
Caught: Username must not be blank
🧱 Custom Exception with Additional Fields
You can add more context to your exception:
class ApiException(val errorCode: Int, message: String) : Exception(message)
🔹 Usage:
throw ApiException(404, "Resource not found")
✔️ Helps carry structured data through exceptions.
🧬 Runtime vs Checked Exceptions in Kotlin
Kotlin doesn’t enforce checked exceptions. You can choose:
- Exception(checked in Java) → For recoverable errors
- RuntimeException→ For programming errors (like- NullPointerException)
class DatabaseException(message: String) : RuntimeException(message)
✔️ Use RuntimeException when it’s the developer’s fault, and Exception for external/environmental issues.
🧩 Inheritance Hierarchy
Custom exceptions can inherit from each other to create a structured exception system:
open class AppException(message: String) : Exception(message)
class AuthException(message: String) : AppException(message)
class NetworkException(message: String) : AppException(message)
✔️ Use parent classes to catch broad errors, and child classes for specific handling.
⚠️ Catching Multiple Custom Exceptions
try {
    throw AuthException("Unauthorized")
} catch (e: AuthException) {
    println("Auth error: ${e.message}")
} catch (e: AppException) {
    println("General app error")
}
🚫 Common Mistakes
| ❌ Mistake | ✅ Fix | 
|---|---|
| Extending Throwabledirectly | Extend from ExceptionorRuntimeExceptioninstead | 
| Not adding meaningful error messages | Always include a message for better debugging | 
| Swallowing custom exceptions silently | Log or rethrow them with context | 
| Using generic exceptions everywhere | Define custom types for clear and semantic code | 
✅ Best Practices for Kotlin Custom Exceptions
| Practice | Benefit | 
|---|---|
| Extend ExceptionorRuntimeException | Aligns with platform expectations | 
| Use specific names and messages | Makes debugging and logging easier | 
| Organize in a base exception hierarchy | Enables flexible exception catching strategies | 
| Use for domain-level errors | Improves clarity in service/business layer logic | 
📌 Summary – Recap & Next Steps
Custom exceptions let you define tailored error types that improve code clarity, debuggability, and modularity. Kotlin makes it easy to define and use them, even without checked exceptions.
🔍 Key Takeaways:
- Create a custom exception using class MyException : Exception(...)
- Use RuntimeExceptionfor programming logic errors,Exceptionfor external errors
- Add fields or base classes for structured error handling
- Combine with throw,try-catch, and@Throwsas needed
⚙️ Practical Use:
Custom exceptions are ideal for API failure handling, form validation, business rule violations, and error modeling in layered architecture.
❓ FAQs – Kotlin Custom Exceptions
❓ How do I define a custom exception in Kotlin?
✅ Inherit from Exception or RuntimeException:
class MyException(message: String) : Exception(message)
❓ Should I use Exception or RuntimeException?
✅ Use RuntimeException for logic bugs (nulls, illegal states). Use Exception for environmental or recoverable issues.
❓ Can I pass extra data in a custom exception?
✅ Yes. Add properties to your class:
class ApiError(val code: Int, message: String) : Exception(message)
❓ Can I catch custom exceptions using their parent class?
✅ Yes. You can create an exception hierarchy and catch using the base type.
❓ Do custom exceptions work with Java code?
✅ Yes. If you’re exposing them to Java, annotate with @Throws(ExceptionType::class) if needed.
Share Now :
