0Pricing
Kotlin Academy · Lekcja

Tworzenie własnych klas wyjątków

Definiuj wyjątki specyficzne dla domeny, wyposażone w zrozumiałe komunikaty i właściwości.

Tworzenie własnych klas wyjątków to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Po co własne wyjątki?

Własne wyjątki kodują znaczenie domenowe: wywołujący mogą przechwytywać je konkretnie, otrzymywać użyteczne komunikaty i reagować inaczej zależnie od typu.

Najprostszy własny wyjątek

Utwórz klasę dziedziczącą po Exception (lub po konkretnym podtypie, takim jak RuntimeException) i przekaż komunikat do konstruktora nadklasy.

class InvalidEmailException(message: String) : Exception(message)
fun main() {
    try {
        throw InvalidEmailException("missing @")
    } catch (e: InvalidEmailException) {
        println("caught: ${e.message}")
    }
}

Wyjątek z właściwościami

Dodaj pola przekazujące kontekst: kod statusu HTTP, nazwę pola, liczbę ponowień i inne informacje.

class HttpError(
    message: String,
    val statusCode: Int
) : Exception(message)
fun main() {
    try {
        throw HttpError("Not Found", 404)
    } catch (e: HttpError) {
        println("HTTP ${e.statusCode}: ${e.message}")
    }
}

Wyjątek z przyczyną

Przekaż cause, aby zachować pierwotny wyjątek w łańcuchu.

class DatabaseError(message: String, cause: Throwable) : Exception(message, cause)
fun main() {
    try {
        try { error("connection refused") }
        catch (e: Throwable) { throw DatabaseError("query failed", e) }
    } catch (e: DatabaseError) {
        println("${e.message} (caused by: ${e.cause?.message})")
    }
}

Wyjątki sprawdzane a niesprawdzane

Kotlin traktuje wszystkie wyjątki jako niesprawdzane (nie trzeba deklarować throws). Zgodnie z konwencją dziedzicz po RuntimeException.

class ValidationException(field: String, message: String) :
    RuntimeException("[$field] $message")
fun main() {
    try {
        throw ValidationException("age", "must be positive")
    } catch (e: ValidationException) {
        println(e.message)
    }
}

Hierarchia wyjątków domenowych

Utwórz hierarchię, aby wywołujący mogli przechwytywać typ bazowy w celu ogólnej obsługi albo konkretne podtypy w szczególnych przypadkach.

open class AppException(message: String) : RuntimeException(message)
class NotFoundException(what: String) : AppException("$what not found")
class UnauthorizedException : AppException("not authorized")
fun main() {
    val errors = listOf(NotFoundException("user"), UnauthorizedException())
    for (e in errors) {
        try { throw e }
        catch (e: AppException) { println("App error: ${e.message}") }
    }
}

Hierarchia wyjątków sealed

W przypadku zamkniętego zbioru typów błędów użyj hierarchii sealed — wywołujący mogą wyczerpująco obsłużyć każdy wariant.

sealed class ApiError(message: String) : RuntimeException(message) {
    class Timeout : ApiError("timeout")
    class NotFound(val id: String) : ApiError("not found: $id")
    class ServerError(val status: Int) : ApiError("server returned $status")
}
fun describe(e: ApiError) = when (e) {
    is ApiError.Timeout -> "request timed out"
    is ApiError.NotFound -> "id ${e.id} missing"
    is ApiError.ServerError -> "5xx: ${e.status}"
}
fun main() {
    println(describe(ApiError.NotFound("user-42")))
}

Konwencja nazewnicza

Dla jasności kończ nazwy własnych klas wyjątków przyrostkiem Exception lub Error. Używaj czasu przeszłego albo rzeczownika (np. NotFound, InvalidInput).

class InvalidInputException(msg: String) : RuntimeException(msg)
class UserNotFoundException(id: Int) : RuntimeException("user $id not found")
fun main() {
    try { throw UserNotFoundException(7) }
    catch (e: UserNotFoundException) { println(e.message) }
}

Dokumentowanie wyjątków

Używaj w KDoc adnotacji @throws, aby udokumentować, jakie wyjątki może zgłaszać funkcja.

/**
 * @throws InvalidEmailException if the email is malformed
 */
fun validate(email: String) {
    if ("@" !in email) throw InvalidEmailException("missing @")
}
class InvalidEmailException(m: String) : RuntimeException(m)
fun main() {
    try { validate("nope") }
    catch (e: InvalidEmailException) { println(e.message) }
}

Unikaj nadużywania wyjątków

Wyjątki służą do sytuacji wyjątkowych. W przypadku oczekiwanych wyników (puste dane wejściowe, brak opcjonalnego pola) preferuj zwracanie wartości null, typy wyników sealed albo wartości domyślne.

fun findUser(id: Int): String? = if (id == 1) "Alice" else null
fun main() {
    val name = findUser(42) ?: "(unknown)"
    println(name) // (unknown), no exception
}

Praktyczny przykład

Realistyczny własny wyjątek dla fikcyjnego klienta API, zawierający kod statusu i treść odpowiedzi.

class ApiException(
    message: String,
    val statusCode: Int,
    val responseBody: String
) : RuntimeException(message)
fun main() {
    try {
        throw ApiException("Bad Request", 400, "{\"error\":\"invalid\"}")
    } catch (e: ApiException) {
        println("[${e.statusCode}] ${e.message}: ${e.responseBody}")
    }
}

Szybkie sprawdzenie

Jaka klasa bazowa jest najczęściej używana podczas definiowania wyjątku domenowego w Kotlinie?

Podsumowanie

Własne wyjątki kodują znaczenie domenowe. Dziedzicz po RuntimeException lub Exception; dodawaj właściwości zapewniające kontekst; zachowuj przyczyny; twórz hierarchie na potrzeby grupowego przechwytywania. Używaj wyjątków sealed dla zamkniętych zbiorów i preferuj typy wartości null lub wyników, gdy błędy są oczekiwane.

Często zadawane pytania

Czy lekcja „Tworzenie własnych klas wyjątków” jest bezpłatna?

Tak — pełny tekst „Tworzenie własnych klas wyjątków” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Tworzenie własnych klas wyjątków”?

Definiuj wyjątki specyficzne dla domeny, wyposażone w zrozumiałe komunikaty i właściwości. Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Tworzenie własnych klas wyjątków”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. try/catch/finally jako wyrażenie
  2. Tworzenie własnych klas wyjątków
  3. runCatching i Result
  4. Ponowne rzucanie wyjątków i ich łańcuchowanie
← Powrót do Kotlin Academy