繁体   English   中英

Scala:错误处理和异常匹配

[英]Scala: Error handling and exception matching

鉴于以下自定义Exception ...

trait ServiceException extends RuntimeException {

  val errorCode: Int
}

object ServiceException {

  def apply(
    message: String, _errorCode: Int
  ): ServiceException = new RuntimeException(message) with ServiceException {
    val errorCode: Int = _errorCode
  }

  def apply(
    message: String, cause: Throwable, _errorCode: Int
  ): ServiceException = new RuntimeException(message, cause) with ServiceException {
    val errorCode: Int = _errorCode
  }
}

...以及以下方法返回Future ...

myService.doSomethingAndReturnFuture.map {
  ...
}.recover {
  case ServiceException(5) =>
    Logger.debug("Error 5")
// this does not work
// case e: ServiceException(5) =>
//   Logger.debug(s"Error 5: ${e.getMessage}")
  case NonFatal(e) =>
    Logger.error("error doing something", e)
}

...如何从ServiceException获取错误消息?

您需要unapply对所描述的匹配项的操作,该匹配项应在伴随对象中定义。

object ServiceException {

   //... apply methods

  def unapply(ex: ServiceException) = Some(ex.errorCode)  
}

然后,您可以进行匹配。

recover {
  case se@ServiceException(5) => println(s"Error 5: ${se.getMessage}")
  case _ => println("Some other error")
}

您还可以将消息包含在unapply

def unapply(ex: ServiceException) = Some((ex.errorCode, ex.getMessage))

然后像这样匹配:

recover {
  case ServiceException(5, msg) => println(s"Error 5: $msg")
  case _ => println("Some other error")
}

或者,您也可以不unapply 然后它看起来像:

recover {
  case se: ServiceException if se.errorCode == 5 => println(s"Error 5: ${se.getMessage}")
  case _ => println("Some other error")
}

人们喜欢案例课。

这并不完全符合您的要求,例如:

scala> trait ServiceException { _: RuntimeException => def errorCode: Int }
defined trait ServiceException

scala> case class MyX(errorCode: Int, msg: String, cause: Exception = null) extends RuntimeException(msg, cause) with ServiceException
defined class MyX

scala> def i: Int = throw MyX(42, "Help!")
i: Int

scala> import concurrent._ ; import ExecutionContext.Implicits._
import concurrent._
import ExecutionContext.Implicits._

scala> Future(i) recover { case MyX(code, m, err) => println(m) ; -1 }
res11: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@7d17ee50

scala> Help!

scala> .value
res12: Option[scala.util.Try[Int]] = Some(Success(-1))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM