我想開發一個控制結構,重試一些聲明的異常但拋出其他異常。控制結構很好地工作,但我有問題檢查,如果捕獲的異常屬於聲明的異常的類型。用更通用的話來說,我該如何檢查參數是否是聲明的類型參數列表之一?檢查斯卡拉重試控制結構中的多個異常
定義的重試控制結構:
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
}
}
}
限定isOneOf函數來檢查聲明和運行時異常類型
def isOneOf[T:scala.reflect.ClassTag](obj:T, cs:Class[_]*) = {
val dc = obj.getClass
val rc = scala.reflect.classTag[T].runtimeClass
cs.exists(c=>c.isAssignableFrom(dc) || c.isAssignableFrom(rc))
}
定義拋出多個異常的功能
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)
}
重試結構,宣告例外列表中在運行時動態傳遞。所以多個異常情況聲明不適用於我。當捕獲異常時,我將它與泛型異常匹配,使用isOneOf函數檢查異常類型。理想情況下,該函數將採用一系列類型,而不是一系列類。我如何傳遞一系列異常類型,而不是一系列的類,並根據類型序列檢查捕獲到的異常?
實際上有很多延遲重試的實現。其中之一 - https://gist.github.com/Mortimerp9/5430595 –
您不能在'retry'方法中使用可變數量的類型標識符。這不僅僅意味着它們的使用方式。您可能堅持傳遞受支持的可重試異常列表。 – cmbaxter