🎓 A1Learner
🔍
0 of 48 lessons completed

Scala Error Recovery

Error recovery is what a program does after a failure so it can still finish usefully. A fallback value is the simplest form of recovery.

GetOrElse turns a failed parse into zero

The good text parses to 42. The bad text falls back to zero instead of throwing.

import scala.util.Try
def parse(s: String): Int = Try(s.toInt).getOrElse(0)
@main def main(): Unit =
  println(parse("42"))
  println(parse("abc"))

Recover replaces one named failure

The bad parse is recovered to minus one. The recovered Try prints as a success.

import scala.util.Try
@main def main(): Unit =
  val recovered = Try("abc".toInt).recover { case e: NumberFormatException => -1 }
  println(recovered)
  println(recovered.getOrElse(0))

OrElse tries the next source when the first is empty

An empty first source falls through to the second source. Two empty sources fall through to zero.

@main def main(): Unit =
  val first: Option[Int] = None
  val second: Option[Int] = Some(5)
  val third: Option[Int] = None
  println(first.orElse(second).getOrElse(0))
  println(first.orElse(third).getOrElse(0))

Example

import scala.util.Try
@main def main(): Unit =
  val inputs = List("10", "xx", "5", "yy", "3")
  val recovered = inputs.map(s => Try(s.toInt).getOrElse(0))
  println(recovered)
  println(recovered.sum)

Key points

  • GetOrElse: getOrElse supplies a fallback when a Try has failed or an Option is empty.
  • Recover: recover turns a named failure into a replacement value.
  • OrElse chain: orElse tries the next source when the first one is empty.
  • Keep going: recovery lets the rest of the program run instead of stopping.

In this example, each input text is parsed with Try and a fallback of zero. The bad texts become zero instead of stopping the program. The recovered list prints first, and its sum prints second.

Note

a fallback should be a safe value, not a guess that hides a real bug.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What does Try("abc".toInt).getOrElse(0) give?