如何更好地匹配Scala中的Java类型?
我有一个从scala异步调用的Web服务。我想匹配并处理一些特定的故障代码,这些代码可以由恢复块中的webservice返回 错误作为SoapFault实例返回,该实例包装在一个附加异常中,因此本质上我需要匹配所有异常,其中 有一个原因是SoapFault的实例 SoapFault消息符合我的要求 到目前为止,我已经有了这样一个可行但繁琐的方法:如何更好地匹配Scala中的Java类型?,java,scala,Java,Scala,我有一个从scala异步调用的Web服务。我想匹配并处理一些特定的故障代码,这些代码可以由恢复块中的webservice返回 错误作为SoapFault实例返回,该实例包装在一个附加异常中,因此本质上我需要匹配所有异常,其中 有一个原因是SoapFault的实例 SoapFault消息符合我的要求 到目前为止,我已经有了这样一个可行但繁琐的方法: call map { result => // handle success } recover { case e: Exce
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
}
}
如何以更少重复的方式更好地执行此操作?恢复块处理在将来执行期间抛出的错误。正如我从你的问题中了解到的,虽然你收到了一个关于某个错误的响应,但它不会抛出任何异常,因为请求本身是成功的。这意味着您需要使用平面图在内部处理您的案例,类似于:
val response = call flatMap {
case SoapFault(error) => Future.failure(error)
// successful response
}
在这种情况下,您的响应将是失败的,因此现在您可以使用恢复块处理错误,但这也不是必需的,因为您可以在flatMap函数中从错误响应中恢复,因为它还返回未来
更新
与lmm建议的一样,您可以使用具有相同名称的提取器,即:
object SoapFault {
def unapply(sf: SoapFault): Option[(Option[String], String)] =
Option((Option(sg.getCause), sf.getMessage))
}
然后在块中解构它:
recover {
case SoapFault(None, "INVALID_INPUT") => // process
}
恢复块处理在将来执行期间抛出的错误。正如我从你的问题中了解到的,虽然你收到了一个关于某个错误的响应,但它不会抛出任何异常,因为请求本身是成功的。这意味着您需要使用平面图在内部处理您的案例,类似于:
val response = call flatMap {
case SoapFault(error) => Future.failure(error)
// successful response
}
在这种情况下,您的响应将是失败的,因此现在您可以使用恢复块处理错误,但这也不是必需的,因为您可以在flatMap函数中从错误响应中恢复,因为它还返回未来
更新
与lmm建议的一样,您可以使用具有相同名称的提取器,即:
object SoapFault {
def unapply(sf: SoapFault): Option[(Option[String], String)] =
Option((Option(sg.getCause), sf.getMessage))
}
然后在块中解构它:
recover {
case SoapFault(None, "INVALID_INPUT") => // process
}
你可以自己创造。类似于未经测试:
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
...
}
你可以自己创造。类似于未经测试:
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
...
}
我已经创建了自己的提取器对象,它类似于,但是它提取错误字符串,而不是在提取器对象中检查错误字符串,这样我就可以匹配case表达式中的特定字符串 提取器:
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
}
}
我已经创建了自己的提取器对象,它类似于,但是它提取错误字符串,而不是在提取器对象中检查错误字符串,这样我就可以匹配case表达式中的特定字符串 提取器:
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
}
}
谢谢SoapFaults实际上出现在recover块中,包装在java异常中。我的代码正在使用recover块-我正在寻找更好的方法。@TomHaigh SoapFault是Throwable的子类型吗?如果是,则可以对其进行匹配,并使用保护来检查消息,即恢复{case sf:SoapFault If sf.getMessage==INVALID_INPUT=>…}。是的,但问题是它被包装为另一个异常的原因,这使得匹配更加困难。i、 e.伪代码异常原因=SoapFault无效\u输入谢谢。SoapFaults实际上出现在recover块中,包装在java异常中。我的代码正在使用recover块-我正在寻找更好的方法。@TomHaigh SoapFault是Throwable的子类型吗?如果是,则可以对其进行匹配,并使用保护来检查消息,即恢复{case sf:SoapFault If sf.getMessage==INVALID_INPUT=>…}。是的,但问题是它被包装为另一个异常的原因,这使得匹配更加困难。i、 e.伪代码异常原因=SoapFault无效\u输入谢谢。我实际上无法编译它:“=>”应为,但已找到。[error]case FaultWithMessageINVALID_INPUT=>{谢谢。我无法实际编译:'=>'预期但找到了。[error]case FaultWithMessageINVALID_INPUT=>{