Here's a silly example that I think will steer you toward an answer:
object Retry
object SO_7331489 extends App {
import scala.util.continuations._
var dividend: String = "ten"
var divisor: Int = 0
val quotient = reset {
shift { k: (Unit => Any) =>
def retry: Any =
k() match {
case Retry => retry
case x => x
}
retry
}
try {
dividend.toInt / divisor
} catch {
case e: java.lang.NumberFormatException =>
println("caught " + e.getClass.getName + "(" + e.getMessage + ")")
dividend = "10"
println("retrying with dividend = \"10\"")
Retry
case e: java.lang.ArithmeticException =>
println("caught " + e.getClass.getName + "(" + e.getMessage + ")")
divisor = 2
println("retrying with divisor = 2")
Retry
case t: Throwable =>
println("caught " + t.getClass.getName + "(" + t.getMessage + ")")
// Nothing left to retry, so don't return Retry
}
}
println("quotient: " + quotient)
}
The idea is to trigger the shift
block before your try/catch
block. Within the catch
block, if you want to retry the whole thing, simply return the Retry
object.
It might be nice to pull the entire shift
block out into a simple function (e.g. retry
), but I left it inline for clarity.
This code produces the following output:
[info] Running SO_7331489
caught java.lang.NumberFormatException(For input string: "ten")
retrying with dividend = "10"
caught java.lang.ArithmeticException(/ by zero)
retrying with divisor = 2
quotient: 5