目前,我的目标是使用 CRUD 方法与 DB 进行通信。在简单的操作之间我可能有一些额外的步骤(额外的业务逻辑可能会引发一些错误)。
import cats.effect.IO
import scalikejdbc._
IO(NamedDB(MyDB) localTx {
implicit session => {
val x = for {
a <- IO(select()) // Option[Something] (1)
_ <- IO(log(a)) // Option[Something] (2)
_ <- IO(insert()) // Something (3)
_ <- IO(insert()) // Something (4)
c <- IO(select()) // Option[Something] (5)
r <- IO(fileSystemOperation(a, c)) // (6)
_ <- operation(r) // Either[Throwable, Unit] (7)
} yield ()
x.unsafeRunSync() // (8)
}
}).attempt.unsafeRunSync() match { // (9)
case Left(value) => println("Error")
case Right(value) => println("Success") // in reality i want to return some result here
}
第一个问题出现(2)
:我收到错误:
错误类型不匹配;发现:cats.effect.IO[Unit] required: Option[?] _ <- IO(log(a))
但是,如果我记录任何插入((3)
或(4)
)的结果,那么一切正常。可能是因为结果类型Option[Something]
vs的不同Something
,但我认为它会与此相同:
for {
a <- Option(1)
....
}
第二个问题是如何正确处理(7)
回滚事务中的错误?我是否必须使用模式匹配并执行以下操作:
operation(r) match {
case Left(e) => throw e
}
或者我可以在我的内部抛出错误operation
并返回Unit
而不是Either[Throwable, Unit]
?
(8)
另外,我对and有疑问(9)
。是否是开始实际处理和处理任何错误的正确方法?
我尝试使用这种方法执行相同的步骤:
select() match {
case Some(_) =>
.....
operation(r) match {
case Left(e) => throw e
case Right(_) => ....
}
case None => ....
}
但结果我得到了太深的match-case
条款,很难阅读和理解。我是 FP 的新手,但我想以 FP 的方式实现它。