如何更好地匹配Scala中的Java类型?

时间:2014-12-10 11:27:33

标签: java scala

我有一个web服务,我从scala异步调用。我想匹配并处理一些特定的故障代码,这些代码可以由recover块中的webservice返回。

错误作为SoapFault实例返回,该实例包含在一个额外的异常中,所以基本上我需要匹配所有异常

  • 有一个原因是SoapFault
  • 的一个实例
  • SoapFault消息符合我的要求

到目前为止,我有这个工作但很麻烦:

call map { result => 
    // handle success
} recover {
    case e: Exception if e.getCause != null && e.getCause.isInstanceOf[SoapFault] && e.getCause.asInstanceOf[SoapFault].getMessage == "INVALID_INPUT" => {
        // handle error
    }
    case e: Exception if e.getCause != null && e.getCause.isInstanceOf[SoapFault] && e.getCause.asInstanceOf[SoapFault].getMessage == "SERVER_BUSY" => {
        // handle error
    }
}

如何以更少的重复更好地完成这项工作?

3 个答案:

答案 0 :(得分:4)

您可以创建自己的Extractor Object。像(未经测试)的东西:

object FaultWithMessage {
  def apply(message: String) = new Object() {
    def unapply(t: Throwable): Boolean = t match {
      case e: Exception if e.getCause != null &&
       e.getCause.isInstanceOf[SoapFault] &&
       e.getCause.asInstanceOf[SoapFault].getMessage == message => true
      case _ => false 
  }
}

... recover {
  case FaultWithMessage("INVALID_INPUT")() =>
    //handle that one
  case FaultWithMessage("SERVER_BUSY")() =>
    //handle that one
  ...
}

答案 1 :(得分:1)

recover块处理在Future执行期间(即内部)抛出的错误。正如我从你的问题中所理解的那样,虽然你收到了一个有关某些错误信号的回复,但它并没有抛出任何异常,因为请求本身是成功的。这意味着您需要使用flatMap处理您的案例,如下所示:

val response = call flatMap {
  case SoapFault(error) => Future.failure(error)
  // successful response
}

在这种情况下,您的回复会失败,所以现在您可以使用recover块来处理错误,但这也不是必需的,因为您可以从{}内部的错误响应中恢复{1}}函数,因为它也会返回flatMap

<强>更新

与提议的Future一样,您可以使用具有相同名称的提取器,即:

lmm

然后在块中解构它:

object SoapFault {
  def unapply(sf: SoapFault): Option[(Option[String], String)] = 
    Option((Option(sg.getCause), sf.getMessage))
}

答案 2 :(得分:0)

我创建了自己的提取器对象,类似于lmm's answer,但它提取错误字符串(而不是在提取器对象中检查它),以便我可以匹配case表达式中的特定字符串。 / p>

萃取器:

 object SoapFaultMessage {
    def unapply(t: Throwable): Option[String] = {
      if (t.getCause != null && t.getCause.isInstanceOf[SoapFault]) {
        Some(t.getCause.asInstanceOf[SoapFault].getMessage)
      } else {
        None
      }
    }
  }

用法:

 .. recover {
    case SoapFaultMessage(msg) if msg == "INVALID_INPUT" => {
      //handle
    }
 }