检查Scala重试控制结构中的多个异常

检查Scala重试控制结构中的多个异常,scala,type-parameter,control-structure,Scala,Type Parameter,Control Structure,我正在尝试开发一种控制结构,可以重试一些已声明的异常,但抛出其他异常。控制结构工作得很好,但是我在检查捕获的异常是否属于声明的异常类型时遇到了问题。更一般地说,如何检查参数是否是已声明的类型参数列表之一 定义重试控制结构: def retry[T, R](times:Int=3, delay:Int=1000)(ex:Class[_<:Exception]*)(t:T)(block:T=>R):R = { try { block(t) } catch { case e:Exc

我正在尝试开发一种控制结构,可以重试一些已声明的异常,但抛出其他异常。控制结构工作得很好,但是我在检查捕获的异常是否属于声明的异常类型时遇到了问题。更一般地说,如何检查参数是否是已声明的类型参数列表之一

定义重试控制结构:

def retry[T, R](times:Int=3, delay:Int=1000)(ex:Class[_<:Exception]*)(t:T)(block:T=>R):R = {
try {
  block(t)
}
catch {
  case e:Exception if (isOneOf(e, ex:_*) && times>0) => {
    println(s"Exception $e happened, sleep $delay milliseconds")
    Thread.sleep(delay)
    println(s"$times times remain for retry before give up")
    retry(times-1, delay)(ex:_*)(t)(block)
  }
  case e:Throwable => {
    println(s"Exception $e is not handled")
    throw e
  }
}
定义一个抛出多个异常的函数

def d(str:String) = {
  val r = Math.random()
  println(r)

  if (r>0.6) throw new IllegalArgumentException
  else if (r>0.4) throw new java.io.IOException
  else if (r>0.2) throw new UnsupportedOperationException
  else println(str)
}
我可以通过重试调用函数,如下所示:

retry(3, 1000)(classOf[IllegalArgumentException], classOf[java.io.IOException])("abc"){
  x=> d(x)
}
我想重试IllegalArgumentException和IOException,但将抛出UnsupportedOperationException

我的目标是像这样调用函数:

retry(3, 1000)[IllegalArgumentException, java.io.IOException]("abc"){
  x=> d(x)
}
def recoverable(throwable: Throwable): Boolean = throwable match {
  case exc @ (_: IllegalArgumentException | _: IOException) => true
  case _ => false
}

对于重试结构,在运行时动态传递已声明异常的列表。所以多个异常情况语句对我不起作用。当捕获到异常时,我将其与泛型异常进行匹配,并使用isOneOf函数检查异常类型。理想情况下,函数将采用类型序列,而不是类序列。如何传入异常类型序列而不是类序列,并根据类型序列检查捕获的异常?

用知道哪些异常是可恢复的(以及可以动态生成的)函数替换异常列表,您认为如何:

可恢复的
函数可能如下所示:

retry(3, 1000)[IllegalArgumentException, java.io.IOException]("abc"){
  x=> d(x)
}
def recoverable(throwable: Throwable): Boolean = throwable match {
  case exc @ (_: IllegalArgumentException | _: IOException) => true
  case _ => false
}

实际上有很多延迟重试的实现。其中之一-不能在
重试
方法上使用数量可变的类型标识符。这不是他们的用意。您可能无法传递支持的可重试异常列表。
if(recoverable(throwable)&×>=0).
在if语句中。因此必须定义可恢复函数和模式绑定器才能使用重试结构。case-exc@(uz:IllegalArgumentException | uz:IOException)=>true相当于case-exc:IllegalArgumentException=>true case-exc:IOException=>true,这两个异常必须在可恢复函数中进行静态编码。这并没有真正简化代码。使用类varargs定义,我可以构建异常列表,以便在运行时重试:val recoverable:Seq[class[_d(x)}你是对的,你应该硬编码它们,但是你不会对“List”做同样的操作吗?我的意思是你将在“retry”函数之外创建一个包含预定义异常的列表,并以同样的方式动态构建一个包含这些异常集的函数。因此,我们的想法是在“retry”之外配置这个列表,你可以对这两个都做些什么。你怎么认为?