Exceptions & Error Handling
19.1 try/catch/finally
try is an expression. Use NonFatal to avoid catching fatal errors (OutOfMemoryError, InterruptedException, ...).
import java.io.*
def readFirstLine(path: String): String =
val reader = BufferedReader(FileReader(path))
try reader.readLine()
catch
case e: FileNotFoundException => s"missing: ${e.getMessage}"
case e: IOException => throw RuntimeException("io failed", e)
case scala.util.control.NonFatal(e) => s"other: $e"
finally reader.close()19.2 Throwing & custom exceptions
Scala has no checked exceptions (use @throws[IOException] for Java callers).
class ValidationException(msg: String) extends Exception(msg)
throw ValidationException("bad input")
require(x > 0, "x must be positive") // IllegalArgumentException
assert(list.nonEmpty) // AssertionError (can be elided)
??? // NotImplementedError placeholder19.3 Resource management with Using
import scala.util.Using
import scala.io.Source
val lines: Try[List[String]] = Using(Source.fromFile("data.txt"))(_.getLines().toList)
Using.resources(openA(), openB()) { (a, b) => ... }19.4 Error-handling strategy
Model expected failures with Option / Either (or effect types).
Wrap throwing APIs at the boundary with Try / Either.catchNonFatal.
Accumulate errors with cats.data.Validated / ValidatedNel.
Let truly unexpected errors propagate to a top-level handler.