αƞjiβ
αƞjiβ

Reputation: 3246

Returning right type in Scala function

I have following code to handle response from rest call. I am trying to convert various HTTP code from server to custom exceptions so that it can be handled by the caller.

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}"))
  }
}

But I am getting compile error as:

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

Any suggestion?

Upvotes: 0

Views: 90

Answers (2)

knutwalker
knutwalker

Reputation: 5974

Within Future#map, you're running a function in case the future completed successfully and are not expected to return a new future (unless you want a Future[Future[...]]. You can either throw these exceptions instead

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}")
  }
}

or use 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}"))
  }
}

Upvotes: 5

Filippo Vitale
Filippo Vitale

Reputation: 8103

Maybe you want to actually flatMap instead of 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}"))
  }
}

Upvotes: 3

Related Questions