---
title: Use Custom Error Classes
impact: HIGH
impactDescription: enables proper error categorization, structured logging, and precise handling
tags: error-handling, custom-errors, exceptions, patterns, quality, kotlin
---

## Use Custom Error Classes

Custom exception classes enable structured error handling, meaningful categorization, and better observability. They allow the application to provide clear diagnostic information and programmatic error codes.

**Incorrect (generic exceptions):**

```kotlin
throw Exception("User not found")
throw RuntimeException("Invalid input")
throw IllegalStateException("Database connection failed")
```

**Correct (custom exception hierarchy):**

```kotlin
// Base application exception
open class AppException(
    val code: String,
    override val message: String,
    val statusCode: Int = 500,
    val context: Map<String, Any?>? = null,
    cause: Throwable? = null
) : RuntimeException(message, cause)

// Specific domain exceptions
class UserNotFoundException(userId: String) : AppException(
    code = "USER_NOT_FOUND",
    message = "User $userId not found",
    statusCode = 404,
    context = mapOf("userId" to userId)
)

class ValidationException(field: String, message: String) : AppException(
    code = "VALIDATION_ERROR",
    message = message,
    statusCode = 400,
    context = mapOf("field" to field)
)

// Usage
throw UserNotFoundException(userId)
```

**Using Sealed Classes for Error Handling (Functional Style):**

```kotlin
sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Failure(val error: AppException) : Result<Nothing>()
}

// Logic returning a result instead of throwing
fun findUser(id: String): Result<User> {
    val user = db.find(id)
    return user?.let { Result.Success(it) } ?: Result.Failure(UserNotFoundException(id))
}
```

**Benefits:**
- Type-safe error handling logic.
- Structured context for logging systems (ELK, Sentry).
- Automatic mapping to API response formats.
- Clearer domain modeling.

**Tools:** detekt (TooGenericExceptionThrown), Manual Review, PR rules
