I've recently seen code like this:
val maybeInt = catching(classOf[NFE]) opt arg.toInt What is this opt? An Option? Why isn't it using getOrElse to extract the value? In the above code, will maybeInt be None if a NumberFormatException gets thrown?
catching looks like it's some sort of method call, doesn't it? It is, but it actually returns an instance of a class Catch; it doesn't directly take an argument. This class has two methods that are particularly useful for dealing with exceptions (and several more for catching multiple exceptions). The first is
def opt [U >: T] (body: ⇒ U) : Option[U] which is being used here--you give it something that may throw an exception, and it will return Some(result) if everything went okay, and None if the targeted exception was caught:
scala> type NFE = NumberFormatException defined type alias NFE scala> import scala.util.control.Exception._ import scala.util.control.Exception._ scala> catching(classOf[NFE]).opt( "fish".toInt ) res0: Option[Int] = None scala> catching(classOf[NFE]).opt( "42".toInt ) res1: Option[Int] = Some(42) You can then deal with this with map or filter or getOrElse or whatever else you use to deal with options.
The other useful method is either, which returns an instance of Left(exception) if an exception was thrown, and a Right(result) if it was not:
scala> catching(classOf[NFE]).either( "fish".toInt ) res2: Either[Throwable,Int] = Left(java.lang.NumberFormatException: For input string: "fish") scala> catching(classOf[NFE]).either( "42".toInt ) res3: Either[Throwable,Int] = Right(42) You can then use fold or map to an option or whatever else you like doing with eithers.
Note that you can define a single catcher and use it multiple times (so you don't need to create the catcher object every time you, for example, parse an integer):
scala> val catcher = catching(classOf[NFE]) catcher: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException) scala> catcher.opt("42".toInt) res4: Option[Int] = Some(42) scala> catcher.opt("fish".toInt) res5: Option[Int] = None Edit: as Daniel points out in the comments, this still creates a temporary Catch[Option]; given the method signatures, there isn't an easy way to just have it trap exceptions and generate options without creating any extra objects. This reminds me why I write my own methods to do exactly that:
def optNFE[T](t: => T) = try { Some(t) } catch {case nfe: NFE => None} optNFE( "fish".toInt ) // gives None optNFE( "42".toInt ) // gives Some(42)
I use a more simple pattern when there is only one catch :
try{ return args.split(" ").exists(line.startsWith _) }catch { case _ =>{//generic exception logger.error("Error with line ${line} for ${ex.message}") throw _ } } I'm definitely not yet a Scala pro, and I guess you could find shorter stuff
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With