Scala:错误处理和异常匹配

j3d*_*j3d 1 scala

鉴于以下自定义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
  }
}
Run Code Online (Sandbox Code Playgroud)

... 和以下方法返回一个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)
}
Run Code Online (Sandbox Code Playgroud)

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

Kig*_*gyo 5

您将需要一个unapply用于描述的匹配项才能工作,它应该在伴随对象中定义。

object ServiceException {

   //... apply methods

  def unapply(ex: ServiceException) = Some(ex.errorCode)  
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以匹配了。

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

您还可以在unapply.

def unapply(ex: ServiceException) = Some((ex.errorCode, ex.getMessage))
Run Code Online (Sandbox Code Playgroud)

然后像这样匹配:

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

作为替代方案,您也可以在没有unapply. 然后它可能看起来像:

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