Каналы ошибок и зависимостей
Типизированные ошибки и окружение
«Каналы ошибок и зависимостей» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Эффект ZIO
- Композиция ZIO
- Каналы ошибок и зависимостей
- Запуск приложений ZIO