0Pricing
Kotlin Academy · Lekcja

DSL Raise w Arrow: składanie typowanych błędów

Użyj kontekstu Raise w Arrow oraz raise(), aby przejrzyście składać przepływy z wieloma błędami.

DSL Raise w Arrow: składanie typowanych błędó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.

Ograniczenia łączenia Either

Łączenie Either za pomocą flatMap prowadzi do głęboko zagnieżdżonych lambd, gdy występuje wiele sekwencyjnych operacji. Raise DSL biblioteki Arrow (wprowadzony w Arrow 1.2) oferuje czytelniejszą składnię w stylu korutyn, korzystającą z odbiorników kontekstu lub funkcji rozszerzających Kotlina.

Czym jest Raise<E>?

Raise to kontekst, który może zgłosić błąd typu E i przerwać dalsze wykonywanie. Funkcja, która może zakończyć się niepowodzeniem, wywołuje raise(error), aby przerwać działanie i propagować błąd — podobnie jak przy rzucaniu wyjątku, ale bez wyjątków.

Konstruktor either { }

Konstruktor either { } tworzy obiekt Either na podstawie bloku, w którym dostępny jest kontekst Raise. Wewnątrz bloku należy wywołać raise(error) w przypadku niepowodzenia albo po prostu zwrócić wartość w przypadku powodzenia:

import arrow.core.raise.either
import arrow.core.raise.Raise

fun validateAge(age: Int): Either<String, Int> = either {
    if (age < 0) raise("Age cannot be negative")
    if (age > 150) raise("Age too large")
    age
}

bind() — rozpakowywanie Either wewnątrz either{}

Wewnątrz bloku either { } należy wywołać .bind() na dowolnej wartości Either, aby ją rozpakować. Jeśli jest to Left, bind() automatycznie zgłasza błąd i przerywa działanie bloku:

fun createUser(name: String, age: Int): Either<String, User> = either {
    val validName = validateName(name).bind()  // raises if Left
    val validAge  = validateAge(age).bind()    // raises if Left
    User(validName, validAge)                  // only reached if both succeed
}

ensure() — sprawdzanie warunku w miejscu użycia

ensure(condition) { error } to skrót dla if (!condition) raise(error). Pozwala zachować zwięzłość logiki walidacji:

fun validateEmail(email: String): Either<String, String> = either {
    ensure(email.contains("@")) { "Email must contain @" }
    ensure(email.length <= 255) { "Email too long" }
    email
}

ensureNotNull() — sprawdzanie wartości null za pomocą Raise

ensureNotNull(value) { error } rozpakowuje wartość nullable albo zgłasza błąd, jeśli jest ona równa null:

fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
    ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}

Raise z odbiornikami kontekstu (Arrow 1.2+)

Można bezpośrednio deklarować funkcje wymagające kontekstu Raise, bez opakowywania ich w either { }:

context(Raise<String>)
fun requirePositive(n: Int): Int {
    ensure(n > 0) { "Must be positive" }
    return n
}

// Called inside either { }
val result = either { requirePositive(-1) }  // Left("Must be positive")

Gromadzenie błędów za pomocą zipOrAccumulate

Domyślnie Raise przerywa działanie po wystąpieniu pierwszego błędu. Należy użyć zipOrAccumulate(), aby wykonać wiele walidacji i zebrać wszystkie błędy w obiekcie NonEmptyList:

val result: Either<NonEmptyList<String>, User> = either {
    zipOrAccumulate(
        { validateName(name).bind() },
        { validateAge(age).bind() }
    ) { validName, validAge -> User(validName, validAge) }
}

recover { } — obsługa konkretnych błędów

Należy użyć recover { error -> ... } wewnątrz either { }, aby obsłużyć konkretny zgłoszony błąd, podać wartość zastępczą i wznowić obliczenia:

val name: String = either {
    findUser(0L).bind().name
}.recover { error ->
    if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"

Raise a łączenie Either: kiedy używać poszczególnych rozwiązań

Należy użyć either { }.bind() w liniowych przepływach z wieloma sekwencyjnymi krokami — kod przypomina wtedy imperatywny, ale pozostaje czysty. Łączenie za pomocą flatMap sprawdzi się w krótkich, dwuetapowych kompozycjach lub podczas integracji z innymi bibliotekami funkcyjnymi.

Testowanie funkcji opartych na Raise

Należy wywołać funkcję wewnątrz either { } i sprawdzić wynik. Matchery Kotest shouldBeLeft() i shouldBeRight() biblioteki Arrow pozwalają zwięźle definiować asercje:

import arrow.core.shouldBeLeft
import arrow.core.shouldBeRight

@Test
fun `negative age returns Left`() {
    validateAge(-1).shouldBeLeft()
}

@Test
fun `valid age returns Right`() {
    validateAge(25).shouldBeRight(25)
}

Szybkie sprawdzenie

Co dzieje się po wywołaniu .bind() na wartości Either.Left wewnątrz bloku either { }?

Podsumowanie: Raise DSL biblioteki Arrow

Najważniejsze informacje:

  • either { } tworzy obiekt Either na podstawie bloku z dostępnym kontekstem Raise
  • .bind() rozpakowuje Either i przerywa działanie po napotkaniu Left
  • ensure(condition) { error } i ensureNotNull(value) { error } służą do sprawdzania warunków w miejscu użycia
  • zipOrAccumulate() służy do zbierania wielu błędów zamiast przerywania działania
  • Kod przypomina imperatywny, a jednocześnie pozostaje czysto funkcyjny

Często zadawane pytania

Czy lekcja „DSL Raise w Arrow: składanie typowanych błędów” jest bezpłatna?

Tak — pełny tekst „DSL Raise w Arrow: składanie typowanych błędó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 „DSL Raise w Arrow: składanie typowanych błędów”?

Użyj kontekstu Raise w Arrow oraz raise(), aby przejrzyście składać przepływy z wieloma błędami. Ć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 „DSL Raise w Arrow: składanie typowanych błędó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. Either : typowana obsługa błędów bez wyjątków
  2. DSL Raise w Arrow: składanie typowanych błędów
  3. Option i nullable: kiedy używać każdego z nich
  4. Funkcjonalne modelowanie domeny za pomocą typów podstawowych Arrow
← Powrót do Kotlin Academy