我有一个catch块,我最后重复了一下,并发现这个SO问题确认我可以使用部分函数作为catch块(Scala 2.9的尝试有什么用例... catch generalization? 1) .
目前,我的代码如下所示:
var task = newTask("update product", "update for customer " + customerId.toString)
try {
val vcdRouter = actorSystem.actorFor("user/supervisor/router-10.10.10.10:443")
val vdcId = new UUID("92ddba5e-8101-4580-b9a5-e3ee6ea5718f")
val vdcGet = sendExpect[AdminVdcType](vcdRouter, GetVdc(vdcId))
val vdcPut = VdcPutConfig(vdcGet, c)
val vdcPutTask = sendExpect[TaskType](vcdRouter, UpdateVdc(vdcId, vdcPut))
task = task.copy(Progress = 100, status = SuccessType)
} catch {
case failure: NoResponseBodyException =>
logger.debug("*** In putCustomerProduct, got a Left(VcdGatewayException)")
task = task.copy(Progress = 100, status = Error, Error = Option(exceptionToError(failure, BadGateway)))
case failure: VcdGatewayException ?
logger.debug("*** In putCustomerProduct, got a Left(VcdGatewayException)")
task = task.copy(Progress = 100, status = Error, Error = Option(exceptionToError(failure, GatewayTimeout)))
case failure: Exception ?
logger.debug("*** In putCustomerProduct, got a Left(Exception)")
task = task.copy(Progress = 100, status = Error, Error = Option(exceptionToError(failure)))
}
Run Code Online (Sandbox Code Playgroud)
因为我有这个任务变量在catch块内部发生了变化,是否有一种很好的方法可以从保存catch块的部分函数中访问它?该任务是一个var,因为它在进入系统时设置了一些初始化数据,如创建的时间戳.我可以解决这个问题,但无论如何我对原始问题的答案感兴趣.
我假设你有几个不同的功能var task,你想用它们.
您可以创建一个将两者task和任务设置器作为参数的函数,它返回一个PartialFunction可用作catch处理程序的函数.
def handler(task: Task, setTask: Task => Any): PartialFunction[Throwable, Any] = {
case failure: NoResponseBodyException =>
logger.debug("*** In putCustomerProduct, got a Left(NoResponseBodyException)")
setTask(task.copy(Progress = 100, status = Error, Error = Option(exceptionToError(failure, BadGateway))))
case failure: VcdGatewayException =>
logger.debug("*** In putCustomerProduct, got a Left(VcdGatewayException)")
setTask(task.copy(Progress = 100, status = Error, Error = Option(exceptionToError(failure, GatewayTimeout))))
case failure: Exception =>
logger.debug("*** In putCustomerProduct, got a Left(Exception)")
setTask(task.copy(Progress = 100, status = Error, Error = Option(exceptionToError(failure))))
}
// somewhere else in your code...
var task = newTask("update product", "update for customer " + customerId.toString)
try {
val vcdRouter = actorSystem.actorFor("user/supervisor/router-10.10.10.10:443")
val vdcId = new UUID("92ddba5e-8101-4580-b9a5-e3ee6ea5718f")
val vdcGet = sendExpect[AdminVdcType](vcdRouter, GetVdc(vdcId))
val vdcPut = VdcPutConfig(vdcGet, c)
val vdcPutTask = sendExpect[TaskType](vcdRouter, UpdateVdc(vdcId, vdcPut))
task = task.copy(Progress = 100, status = SuccessType)
} catch handler(task, task = _)
Run Code Online (Sandbox Code Playgroud)
我也同意user3001你应该尝试减少catch处理程序中的重复.
这是另一种使用方式scala.util.control.Exception.
scala> import util.control.Exception._
import util.control.Exception._
Run Code Online (Sandbox Code Playgroud)
首先创建Catch[_]对象以处理特定异常.
scala> val nfeh = handling(classOf[NumberFormatException]) by println
nfeh: util.control.Exception.Catch[Unit] = Catch()
scala> val aobeh = handling(classOf[ArrayIndexOutOfBoundsException]) by println
aobeh: util.control.Exception.Catch[Unit] = Catch()
Run Code Online (Sandbox Code Playgroud)
使用.or方法将它们组合在一起.请注意,就像在catch块中一样,顺序很重要.
scala> val h = nfeh or aobeh
h: util.control.Exception.Catch[Unit] = Catch()
Run Code Online (Sandbox Code Playgroud)
将处理程序应用于可能引发异常的代码.
scala> h apply {
| println("1o2".toInt)
| }
java.lang.NumberFormatException: For input string: "1o2"
scala> h apply {
| val x = Array(8)
| println(x(2))
| }
java.lang.ArrayIndexOutOfBoundsException: 2
Run Code Online (Sandbox Code Playgroud)
至于task部分,您可以按以下方式执行操作:
scala> val nfeh = handling(classOf[NumberFormatException]) by { ex =>
| println(ex)
| -1
| }
nfeh: util.control.Exception.Catch[Int] = Catch()
scala> val aobeh = handling(classOf[ArrayIndexOutOfBoundsException]) by { ex =>
| println(ex)
| -2
| }
aobeh: util.control.Exception.Catch[Int] = Catch()
scala> val h = nfeh or aobeh
h: util.control.Exception.Catch[Int] = Catch()
scala> val task = h apply {
| "120".toInt
| }
task: Int = 120
scala> val task = h apply {
| "12o".toInt
| }
java.lang.NumberFormatException: For input string: "12o"
task: Int = -1
scala> val task = h apply {
| Array(12, 33, 22)(2)
| }
task: Int = 22
scala> val task = h apply {
| Array(12, 33, 22)(6)
| }
java.lang.ArrayIndexOutOfBoundsException: 6
task: Int = -2
Run Code Online (Sandbox Code Playgroud)