Scala for Backend Engineering & Functional Programming · 课时

IO 中的错误处理

handleError

第 4 / 4 课13 个步骤

IO 中的错误处理 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 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 后,您可以通过对 Either 使用普通的 flatMap,分别处理成功和失败的分支。

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))

普通 Scala 的 try/catch

请将其与普通 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 课程。

免费开始

用 AI 导师学习 Scala — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
39
课程
143

常见问题解答

「IO 中的错误处理」课时是免费的吗?

是的 — 「IO 中的错误处理」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「IO 中的错误处理」这节课中我会学到什么?

handleError 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 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