Я пытаюсь разработать структуру управления, которая повторяет некоторые объявленные исключения, но бросает других. Структура управления работает хорошо, но у меня есть проблема с проверкой, если обнаруженное исключение относится к типам объявленных исключений. В более общих словах, как проверить, является ли параметр одним из объявленных списков параметров типа?Проверить несколько исключений в структуре управления повторной попыткой Scala
Определить структуру управления Retry:
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