在Scala函数中返回正确的类型

时间:2015-12-23 01:09:08

标签: scala

我有以下代码来处理来自其余调用的响应。我正在尝试将各种HTTP代码从服务器转换为自定义异常,以便调用者可以处理它。

def handleResponse(eventualResponse: Future[WSResponse]): Future[WSResponse] = eventualResponse.map { response =>
  response.status match {
    case x if x >= 200 && x <= 204 => response
    case x if x==403 => Future.failed(new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}"))
    case x if x >= 500 => Future.failed(new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}"))
    case _ => Future.failed(new NoRetryException(s"Non-Retryable Exception ${response.status} - ${response.body}"))
  }
}

但我收到编译错误:

found   : scala.concurrent.Future[Nothing]
required: play.api.libs.ws.WSResponse

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

Future#map范围内,如果未来成功完成并且预计不会返回新的未来,您将运行一项功能(除非您想要一个Future[Future[...]] 。 您可以改为抛出这些异常

def handleResponse(eventualResponse: Future[WSResponse]): Future[WSResponse] = eventualResponse.map { response =>
  response.status match {
    case x if x >= 200 && x <= 204 => response
    case 403 => throw new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}")
    case x if x >= 500 => throw new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}")
    case _ => throw new NoRetryException(s"Non-Retryable Exception ${response.status} - ${response.body}")
  }
}

或使用flatMap

def handleResponse(eventualResponse: Future[WSResponse]): Future[WSResponse] = eventualResponse.flatMap { response =>
  response.status match {
    case x if x >= 200 && x <= 204 => Future.successful(response)
    case x if x==403 => Future.failed(new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}"))
    case x if x >= 500 => Future.failed(new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}"))
    case _ => Future.failed(new NoRetryException(s"Non-Retryable Exception ${response.status} - ${response.body}"))
  }
}

答案 1 :(得分:3)

也许你想要实际flatMap而不是map

def handleResponse(eventualResponse: Future[WSResponse]): Future[WSResponse] = eventualResponse.flatMap { response =>
  response.status match {
    case x if x >= 200 && x <= 204 => Future.successful(response)
    case x if x==403               => Future.failed(new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}"))
    case x if x >= 500             => Future.failed(new RetryExternalException(s"Retryable Exception ${response.status} - ${response.body}"))
    case _                         => Future.failed(new NoRetryException(s"Non-Retryable Exception ${response.status} - ${response.body}"))
  }
}