Obsługa błędów w IO
handleError
Obsługa błędów w IO to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 4 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 Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Błędy jako wartości
W Cats Effect obiekt IO może zakończyć się błędem. Błąd jest częścią wartości, więc można go analizować i obsługiwać bez nieuporządkowanego try/catch.
Zgłaszanie błędów
Użyj IO.raiseError, aby jawnie utworzyć nieudane IO z wybranym wyjątkiem.
import cats.effect.IO
val failed: IO[Int] =
IO.raiseError(new RuntimeException("boom"))handleError
handleError obsługuje nieudane IO, dostarczając wartość zastępczą obliczoną na podstawie błędu. Wynik jest obiektem IO, który na tym etapie nie może już zakończyć się błędem.
import cats.effect.IO
val safe: IO[Int] =
IO.raiseError[Int](new RuntimeException("x"))
.handleError(_ => -1)handleErrorWith
handleErrorWith obsługuje błąd za pomocą innego IO, dzięki czemu działanie zastępcze może samo być efektem (np. logowaniem, ponowieniem próby lub zwróceniem wartości domyślnej).
import cats.effect.IO
val recovered: IO[Int] =
IO(throw new RuntimeException("fail"))
.handleErrorWith(e => IO.println(s"caught: ${e.getMessage}").as(0))attempt
attempt przekształca IO[A] w IO[Either[Throwable, A]], materializując błąd jako wartość, aby można było dopasować do niego wzorzec.
import cats.effect.IO
val e: IO[Either[Throwable, Int]] =
IO.raiseError[Int](new RuntimeException("oops")).attemptDopasowanie wzorca po attempt
Po użyciu attempt można rozgałęzić obsługę sukcesu i błędu za pomocą zwykłego flatMap na obiekcie Either.
import cats.effect.IO
val prog: IO[Unit] = IO(10 / 2).attempt.flatMap {
case Right(v) => IO.println(s"ok: $v")
case Left(e) => IO.println(s"err: ${e.getMessage}")
}redeem
redeem obsługuje obie gałęzie w jednym wywołaniu: jedna funkcja obsługuje błąd, druga sukces, a obie zwracają zwykłą wartość.
import cats.effect.IO
val label: IO[String] =
IO(42).redeem(e => s"failed: $e", v => s"value: $v")redeemWith
redeemWith działa podobnie jak redeem, ale każda gałąź zwraca IO, co pozwala na efektywną obsługę zarówno sukcesu, jak i błędu.
import cats.effect.IO
val prog: IO[Unit] = IO(42).redeemWith(
e => IO.println(s"err: $e"),
v => IO.println(s"got: $v")
)Sprzątanie za pomocą guarantee
guarantee uruchamia finalizer niezależnie od tego, czy efekt zakończy się sukcesem, czy błędem — doskonale nadaje się do zwalniania zasobów lub rejestrowania zakończenia.
import cats.effect.IO
val prog: IO[Int] =
IO(compute()).guarantee(IO.println("done"))
def compute(): Int = 7Ponawianie po błędzie
Możesz zbudować prosty mechanizm ponawiania, rekurencyjnie obsługując błąd za pomocą handleErrorWith i zmniejszając licznik aż do zera.
import cats.effect.IO
def retry[A](io: IO[A], n: Int): IO[A] =
if (n <= 0) io
else io.handleErrorWith(_ => retry(io, n - 1))try/catch w zwykłej Scali
Dla porównania zobacz klasyczną, zachłanną obsługę błędów w zwykłej Scali. Kombinatory IO zapewniają to samo bezpieczeństwo, ale jako komponowalne, czyste wartości.
object Main {
def main(args: Array[String]): Unit = {
val result = try { 10 / 0 } catch { case _: ArithmeticException => -1 }
println(s"result: $result")
}
}Szybkie sprawdzenie
Która metoda przekształca IO[A] w IO[Either[Throwable, A]]?
Podsumowanie
Obsługiwałeś błędy w IO za pomocą:
raiseErrordo jawnego zgłaszania błędówhandleError/handleErrorWithdo obsługi błędówattemptdo materializowaniaEitherredeem/redeemWithdo obsługi obu gałęziguaranteedo sprzątania
Ukończyłeś kurs Cats i IO.
Często zadawane pytania
Czy lekcja „Obsługa błędów w IO” jest bezpłatna?
Tak — pełny tekst „Obsługa błędów w IO” 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 Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Obsługa błędów w IO”?
handleError Ćwiczysz Scala for Backend Engineering & Functional Programming 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ąć Scala for Backend Engineering & Functional Programming?
Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming 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 4 z 4.
Ile czasu zajmuje lekcja „Obsługa błędów w IO”?
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 Scala for Backend Engineering & Functional Programming?
Tak. Każda lekcja Scala for Backend Engineering & Functional Programming 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
- Type classy Cats
- Monada IO
- Komponowanie IO
- Obsługa błędów w IO