0Pricing
Scala for Backend Engineering & Functional Programming · Урок

Обработка ошибок в IO

handleError

«Обработка ошибок в IO» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Ошибки как значения

В Cats Effect объект IO может завершиться с ошибкой. Ошибка является частью значения, поэтому её можно исследовать и обрабатывать без неструктурированного try/catch.

Выдача ошибок

Используйте IO.raiseError, чтобы явно создать неуспешный IO с выбранным исключением.

import cats.effect.IO

val failed: IO[Int] =
  IO.raiseError(new RuntimeException("boom"))

handleError

handleError обрабатывает неуспешный IO, подставляя резервное значение, вычисленное на основе ошибки. В результате получается IO, который на этом этапе уже не может завершиться с ошибкой.

import cats.effect.IO

val safe: IO[Int] =
  IO.raiseError[Int](new RuntimeException("x"))
    .handleError(_ => -1)

handleErrorWith

handleErrorWith выполняет восстановление с помощью другого IO, поэтому резервное действие само может иметь эффекты (например, вести журнал, повторять попытку или возвращать значение по умолчанию).

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 преобразует IO[A] в IO[Either[Throwable, A]], материализуя ошибку в значении, чтобы вы могли сопоставить его с шаблоном.

import cats.effect.IO

val e: IO[Either[Throwable, Int]] =
  IO.raiseError[Int](new RuntimeException("oops")).attempt

Сопоставление с шаблоном после attempt

После attempt вы можете выбрать ветвь для успешного или неуспешного результата с помощью обычного flatMap над 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 обрабатывает обе ветви одним вызовом: одна функция предназначена для ошибки, другая — для успеха, и обе возвращают обычное значение.

import cats.effect.IO

val label: IO[String] =
  IO(42).redeem(e => s"failed: $e", v => s"value: $v")

redeemWith

redeemWith похож на redeem, но каждая ветвь возвращает IO, что позволяет обрабатывать успех и ошибку с эффектами.

import cats.effect.IO

val prog: IO[Unit] = IO(42).redeemWith(
  e => IO.println(s"err: $e"),
  v => IO.println(s"got: $v")
)

Очистка с помощью guarantee

guarantee выполняет финализатор независимо от того, завершился эффект успешно или с ошибкой. Это идеально подходит для освобождения ресурсов или записи завершения в журнал.

import cats.effect.IO

val prog: IO[Int] =
  IO(compute()).guarantee(IO.println("done"))

def compute(): Int = 7

Повтор при ошибке

Вы можете реализовать простой повтор, рекурсивно выполняя восстановление с помощью handleErrorWith и уменьшая счётчик до нуля.

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 в обычной Scala

Сравните это с классической нетерпеливой обработкой ошибок в обычной Scala. Комбинаторы IO обеспечивают такую же безопасность, но в виде компонуемых чистых значений.

object Main {
  def main(args: Array[String]): Unit = {
    val result = try { 10 / 0 } catch { case _: ArithmeticException => -1 }
    println(s"result: $result")
  }
}

Быстрая проверка

Какой метод преобразует IO[A] в IO[Either[Throwable, A]]?

Итоги

Вы обрабатывали ошибки в IO с помощью:

  • raiseError для явного завершения с ошибкой
  • handleError / handleErrorWith для восстановления
  • attempt для материализации Either
  • redeem / redeemWith для обработки обеих ветвей
  • guarantee для очистки

Вы завершили курс по Cats и IO.

Часто задаваемые вопросы

Урок «Обработка ошибок в IO» бесплатный?

Да — полный текст урока «Обработка ошибок в IO» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Чему я научусь в уроке «Обработка ошибок в IO»?

handleError Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?

Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Обработка ошибок в IO»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?

Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Классы типов Cats
  2. Монада IO
  3. Композиция IO
  4. Обработка ошибок в IO
← Назад к Scala for Backend Engineering & Functional Programming