TheDude
TheDude

Reputation: 391

What can i use to write this scala code better?

functionThatReturnsATry[Boolean]() match {
      case Success(value) =>
        value match {
          case true => somethingThatReturnsFuture[Unit]
          case false =>
            Failure(new SomeException("This failed here"))
        }
      case Failure(exception) => Failure(exception)
    }

The code will return Future[Unit] when functionThatReturnsATry finishes succesfully and returns true.
If functionThatReturnsATry fails, i want to pass that failure up the chain.
If functionThatReturnsATry returns false, i want to pass a new sepecific failure up the chain

Upvotes: 1

Views: 87

Answers (4)

Scalway
Scalway

Reputation: 1663

functionThatReturnsATry[Boolean]() match {
  case Success(true) => somethingThatReturnsFuture[Unit]
  case Success(false) => Future.failed(new SomeException("This failed here"))
  case Failure(exception) => Future.failed(exception)
}

https://scalafiddle.io/sf/DSaGvul/0

Upvotes: 2

jwvh
jwvh

Reputation: 51271

I'd be tempted to fold() over the Try.

functionThatReturnsATryBool()
  .fold(Future.failed
       ,if (_) somethingThatReturnsFutureUnit()
        else Future.failed(new SomeException("This failed here"))
       )

The result is type Future[Unit] with either type of failure returned as Future(Failure(java.lang.Exception(...))). No loss of error message.

Upvotes: 2

stefanobaghino
stefanobaghino

Reputation: 12804

I like the existing answer, but as an alternative, if you don't care about controlling the precise exception of the first step, you can wrap your Try in a Future and use a for-comprehension:

def attempt(): Try[Boolean] = Success(true)
def soon(): Future[Unit] = Future.failed(new RuntimeException("uh"))

for {
  success <- Future.fromTry(attempt()) if success
  result <- soon()
} yield result

The code is available here on Scastie.

Upvotes: 3

Tim
Tim

Reputation: 27356

One improvement would be to use guard expressions on the match to separate the three different cases. You should also return Future.failed rather than Failure so that the result is Future[Unit] not Any:

functionThatReturnsATry[Boolean]() match {
  case Success(value) if value =>
    somethingThatReturnsFuture[Unit]

  case Success(_) =>
    Future.failed(new SomeException("This failed here"))

  case Failure(exception) =>
    Future.failed(exception)
}

Upvotes: 5

Related Questions