[英]Scala: Exception Pattern Matching
我需要定義一個提供上下文信息的Exception
,並將此信息存儲在Map
。 為了避免錯誤的鍵名,我定義了以下Enumeration
:
object ContextValueName extends Enumeration {
type ContextValueName = Value
val Value1 = Value("Value1")
val Value2 = Value("Value2")
val ValueN = Value("ValueN")
implicit def toString(name: ContextValueName) = name.toString
}
這是Exception
代碼:
import ContextValueName._
trait MyException extends RuntimeException {
val errorCode: Int
val contextValues: Map[ContextValueName, Option[String]]
}
object MyException {
def apply(
message: String, _errorCode: Int, _contextValues: Map[ContextValueName, Option[String]]
): MyException = new RuntimeException(message) with MyException {
val errorCode: Int = _errorCode
val contextValues: Map[ContextValueName, Option[String]] = _contextValues.withDefault(_ => None)
}
def unapply(exception: MyException) = {
if (exception eq null) None
else Some((
exception.errorCode,
exception.contextValues
))
}
}
最后,這是我如何處理MyException
類型的MyException
:
callService("myService").map { result =>
...
}.recover {
case e@MyException(1, contextValues) =>
Logger.debug(s"error invoking myService: ${contextValues(Value1).get}")
case NonFatal(e) =>
Logger.error(s"unhandled error: ${e.getMessage}")
}
問題是,即使拋出的異常類似於MyException(1, Map(Value1 -> "too busy"))
,也永遠不會執行第一個case
語句,並且執行始終落在最后一個case
語句中。 我想念什么嗎?
也許您可以使用Try,這對於Scala來說應該更自然一些。
Try {
callService("myService")
} match {
case Success(s) => // something you do when you succeed
case Failure(ex) => ex match {
case ex@MyException(1, contextValues) =>
Logger.debug(s"error invoking myService: ${contextValues(Value1).get}")
case NonFatal(ex) =>
Logger.error(s"unhandled error: ${ex.getMessage}")
}
}
小安慰,但FWIW,IWFM。
object Test extends App {
import util._
val res = Try (throw MyException("help", 1, Map(Value1 -> Option("bad")))) recover {
case e@MyException(1, vals) => vals
}
Console println res
import concurrent._
import duration.Duration._
import ExecutionContext.Implicits._
val f = Future (throw MyException("help", 1, Map(Value1 -> Option("bad")))) recover {
case e@MyException(1, vals) => vals
}
Console println Await.result(f, Inf)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.