我发现自己重复了简单的try / catch块,IMO应该是1行。
例如,假设我需要将yyyymmdd格式的uri字符串日期转换为Joda-Time。使用标准的try / catch块,转换方法如下所示:
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")
运作良好,意图很明确,但当我为所有非关键事件进行此类尝试/捕获日志记录时,我会寻找一种方法来干掉它。搜索引导我在scala.util.control.Exception上发现SO post。很有帮助,但是按照我喜欢的方式制作/使它工作仍然有点困难。用简单的英语我只想说,“抓住一些动作get-result log-error-type”。
所以,我基于control.Exception感兴趣(或理解为有用)感染了这个:
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)
然后用它代替try / catch:
catching( ymdFormat.parseDateTime(date) ) either log.info
可以添加选项,一个msg前缀等,但是......找到一种获得control.Exception的方法可能会更好,就像上面那样工作,因为TypeSafe工作人员将更好地生成代码世界比我想象的要好。
有没有人知道如何使用control.Exception创建这种语法,其中一个可以传入一个记录器函数的名字来在catch块中使用?
如果有一个“用例”用于control.Exception会很好,但我觉得这个实用程序适用于更高级的Scala开发人员
答案 0 :(得分:7)
这应该做你想要的:
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))
但在我看来,Scalaz Validation
可以更好地处理这种事情。
答案 1 :(得分:3)
一个简单的例子:
import scala.util.control.Exception._
def throwingStuff {
throw new Exception("Hello World!")
}
catching(classOf[Exception]).withApply{err => println(err.toString); None}.apply(Some(throwingStuff))
您可以使用withApply
覆盖Catch
类的应用程序逻辑来执行诸如写入日志之类的操作。