nobody
nobody

Reputation: 1949

recover from an Exception, scala Future

Why does this scala code compile, The signature of recover is,

def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U]

then why does below code compile. You can see that recover in below code doesn't return a Unit.

 object TestRecover {

    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.Future

    def failingFunction(input: Seq[String]): Future[Unit] = {
      Future {
        if (input.isEmpty) throw new Exception("Cannot be empty")
        else ()
      }
    }

    def callFailingFunc(input: Seq[String]): Future[Unit] = {
      failingFunction(input).recover {
        case _ =>
          //Not returning Unit here, but Future[Unit]. Shouldn't type checker fail this ?
          callFailingFunc(input.reverse)
      }
    }
  }

Also why Await.result(TestRecover.callFailingFunc(Seq()), 20.seconds) doesn't produce stackoverflow because of infinite recursion ?

Upvotes: 3

Views: 653

Answers (1)

Pim Verkerk
Pim Verkerk

Reputation: 1066

then why does below code compile. You can see that recover in below code doesn't return a Unit.

The compiler is 'helping' you a bit and does an implicit conversion from Future[Unit] to Unit. Effectively compiling it like this.

def callFailingFunc(input: Seq[String]): Future[Unit] = {
  failingFunction(input).recover {
    case _ =>
      //Not returning Unit here, but Future[Unit]. Shouldn't type checker fail this ?
      callFailingFunc(input.reverse)
      ()
  }
}

This blog explains is very nicely: http://blog.bruchez.name/2012/10/implicit-conversion-to-unit-type-in.html

Also why Await.result(TestRecover.callFailingFunc(Seq()), 20.seconds) doesn't produce stackoverflow because of infinite recursion ?

You don't get a stack overflow because every call to failingFunction will create a new Future with a new stack.

Upvotes: 3

Related Questions