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

Каналы ошибок и зависимостей

Типизированные ошибки и окружение

Урок 3 из 413 шагов

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

Два мощных канала

Помимо успешного значения, ZIO[R, E, A] отслеживает канал типизированных ошибок E и канал зависимостей R. Оба видны в типе, поэтому сбои и требования становятся явными во время компиляции.

Типизированные ошибки

Представьте ошибки предметной области в виде запечатанной иерархии и поместите её в E. После этого компилятор заставит Вас обработать ровно эти случаи.

import zio._

sealed trait AppError
case object NotFound extends AppError
case object Forbidden extends AppError

val lookup: IO[AppError, String] = ZIO.fail(NotFound)

Восстановление с помощью catchAll

catchAll обрабатывает каждую ошибку в E, предоставляя новый эффект. После этого канал ошибок может стать Nothing, если ошибки полностью обработаны.

import zio._

val safe: UIO[String] =
  ZIO.fail("boom").catchAll(e => ZIO.succeed(s"recovered: $e"))

catchSome и orElse

catchSome обрабатывает только подходящие ошибки. orElse при любом сбое переключается на другой эффект.

import zio._

val prog = ZIO.fail("x").orElse(ZIO.succeed("fallback"))

Either и fold

either преобразует ZIO[R, E, A] в ZIO[R, Nothing, Either[E, A]]. fold обрабатывает ошибку и успешный результат, объединяя их в одно значение.

import zio._

val label: UIO[String] =
  ZIO.fail(404).fold(e => s"err $e", v => s"ok $v")

Дефекты и сбои

ZIO различает сбои (типизированные, ожидаемые, находящиеся в E) и дефекты (неожиданные исключения). ZIO.die вызывает дефект; дефекты не входят в тип E и обозначают ошибки в программе.

Окружение R

Канал R объявляет службы, необходимые эффекту. Получить службу можно с помощью ZIO.service; требование остаётся в R, пока служба не будет предоставлена.

import zio._

trait Logger { def log(s: String): UIO[Unit] }

val prog: ZIO[Logger, Nothing, Unit] =
  ZIO.serviceWithZIO[Logger](_.log("hello"))

Определение службы

Служба — это трейт и ZLayer, который его создаёт. Слои описывают построение зависимостей и сами могут зависеть от других слоёв.

import zio._

case class ConsoleLogger() extends Logger {
  def log(s: String): UIO[Unit] = ZIO.succeed(println(s))
}
object ConsoleLogger {
  val layer: ULayer[Logger] = ZLayer.succeed(ConsoleLogger())
}

trait Logger { def log(s: String): UIO[Unit] }

Предоставление зависимостей

provide (или provideLayer) удовлетворяет требование R, превращая ZIO[Logger, E, A] в готовый к запуску ZIO[Any, E, A].

import zio._

val runnable: UIO[Unit] =
  ZIO.serviceWithZIO[Logger](_.log("hi"))
    .provide(ConsoleLogger.layer)

trait Logger { def log(s: String): UIO[Unit] }
object ConsoleLogger { val layer: ULayer[Logger] = ??? }

Композиция слоёв

Слои можно объединять по горизонтали с помощью ++ и по вертикали с помощью >>>, передавая результат одного слоя на вход другому и создавая полный граф зависимостей.

import zio._

// val appLayer = configLayer ++ (dbLayer >>> repoLayer)

Базовый вариант на чистой Scala

Для сравнения рассмотрим автономную программу на Scala с ручной обработкой ошибок. ZIO кодирует ту же ошибку в типе и внедряет зависимости через слои.

object Main {
  def main(args: Array[String]): Unit = {
    val result: Either[String, Int] = Left("NotFound")
    val msg = result.fold(e => s"err $e", v => s"ok $v")
    println(msg)
  }
}

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

Что делает метод provide с объектом ZIO[Logger, E, A]?

Итоги

Вы работали с обоими дополнительными каналами:

  • Ошибки: тип E, catchAll, orElse, fold, дефекты и сбои
  • Зависимости: R, службы, ZLayer, provide, композиция слоёв

Далее: запуск приложений ZIO.

Можно начать бесплатно

Изучай Scala с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
39
Уроки
143

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

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

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

Чему я научусь в уроке «Каналы ошибок и зависимостей»?

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

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

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

Сколько времени занимает урок «Каналы ошибок и зависимостей»?

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

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

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

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

  1. Эффект ZIO
  2. Композиция ZIO
  3. Каналы ошибок и зависимостей
  4. Запуск приложений ZIO
← Назад к Scala for Backend Engineering & Functional Programming