想知道是否有更好的技术来实现Any
上的函数链接,如果遇到APIException
对象将停止链(不必扩展Throwable
或{ {1}},或使用Exception
)。此外,我宁愿不使用throw
(让我头晕)
scalaz
一直到最后并返回。这是一个测试规范:
APIException
这是我提出的一个实现,寻找对此的改进。
class FailFastChainSpec extends PlaySpec {
import utils.Ops._
def fFailsValidation(): Option[APIException] = Some(UnknownException())
def fPassesValidation(): Option[APIException] = None
def someCalculation = "Results"
"Utils" when {
"FailFastChaining" must {
"return Left(APIException) when encountered (at beginning of chain)" in {
fFailsValidation |> {
someCalculation
} mustBe Left(UnknownException())
}
"return Right(...) when no APIExceptions are encountered" in {
fPassesValidation |> {
someCalculation
} mustBe Right(someCalculation)
}
"return Left(APIException) when encountered (in middle of chain with 1 link)" in {
fPassesValidation |> fFailsValidation mustBe Left(UnknownException())
}
"return Left(APIException) when encountered (at end of chain with 1 link)" in {
fPassesValidation |> {
Left(UnknownException())
} mustBe Left(UnknownException())
}
"return Left(APIException) when encountered (at end of chain with 2 links)" in {
fPassesValidation |> fPassesValidation |> {
Left(UnknownException())
} mustBe Left(UnknownException())
}
"return Right(...) when no APIExceptions are encountered (multiple links)" in {
fPassesValidation |> fPassesValidation |> fPassesValidation |> fPassesValidation |> {
Right(someCalculation)
} mustBe Right(someCalculation)
}
"return Right(...) when no APIExceptions are encountered (complex multiple links)" in {
fPassesValidation |> fPassesValidation |> {
Right("Cupcakes")
} |> fPassesValidation |> {
Right(someCalculation)
} mustBe Right(someCalculation)
}
}
}
}
答案 0 :(得分:0)
如果将Option
类型与for comprehension结合使用,则可以模拟monadic行为:
import scala.util.control.Exception._
import scala.util._
def dangerousOp = throw new RuntimeException("never works")
def f1(s: Int): Try[Int] = Success(s * 10)
def f2(s: Int): Try[Int] = catching(classOf[Exception]) toTry dangerousOp
def f3(s: Int): Try[Int] = Success(s * 30)
val result = for {
x <- f1(10)
y <- f2(x)
z <- f3(y)
} yield z
println(result) // Failure(java.lang.RuntimeException: never works)
如果其中任何一个失败并且没有,则无将传播到收益。
编辑:示例方法f2
现在抛出异常以显示如何将它们集成到此链中。也改为尝试使其更像你的例子。