Scala DRYing try/catch
dry, logging, scala, try-catch
Solution
This should do what you want:
import scala.util.control.Exception
def log(logger: => Logger)(e: Throwable) = {
logger(e.getMessage)
None
}
Exception.allCatch withApply log(logger) apply Some(ymdFormat.parseDateTime(date))
But this kind of stuff is better handled by Scalaz `Validation`, in my opinion.
Problem
I find myself repeating simple try/catch blocks that should, IMO, be 1-liners. For example, let's say I need to convert a uri string date in yyyymmdd format to Joda-Time. With a standard try/catch block the conversion method looks like: ``` def ymd2Date(ymd: Option[String]) = ymd match { case Some(date) => try { Right( ymdFormat.parseDateTime(date) ) } catch { case e => log.info(e.getMessage) Left(None) } case None => Left(None) // no uri date param } val ymdFormat = DateTimeFormat.forPattern("yyyyMMdd") ``` Works well enough, intent is clear, but when I do this kind of try/catch logging for all non-critical events, then I seek a way to DRY it out. The search led me to this SO post on scala.util.control.Exception. Helpful, but it's still a bit difficult to grok/make it work in the way I'd like it to. In plain English I just want to say, "catch some-action get-result log-error-type". So, I hacked this out based on the part of control.Exception I'm interested in (or understand to be useful): ``` class Catcher[T](f: => T) { type Logger = (=> Any) => Unit def either[T]( logger: => Logger ) = { try { Right(f) } catch { case e => logger(e.getMessage) Left(None) } } } def catching[T](f: => T) = new Catcher(f) ``` And then use in place of try/catch like so: ``` catching( ymdFormat.parseDateTime(date) ) either log.info ``` Can add on option, a msg prefix, etc., but...it would probably be better to find a way to get control.Exception to work like the above, as the TypeSafe crew is going to produce code worlds better than I'll ever imagine writing. Does anyone know how to create this kind of syntax using control.Exception where one can pass in a logger function by-name to be used in the catch block? Would be great if there was a "use cases" for control.Exception, but I get the feeling this utility is for more advanced Scala devs