6

What happens when an actor of a future throws an exception?

According to the Akka documentation at http://doc.akka.io/docs/akka/snapshot/scala/futures.html:

It doesn't matter if an Actor or the dispatcher is completing the Future, if an Exception is caught the Future will contain it instead of a valid result. If a Future does contain an Exception, calling Await.result will cause it to be thrown again so it can be handled properly.

I am not sure this is what I am seeing when running this piece of code:

  class Worker extends Actor {
    def receive = {
      case i: Int => throw new RuntimeException
    }         
  }

  implicit val system = ActorSystem("MySystem")
  val worker = system.actorOf(Props(new Worker), name="worker")
  implicit val timeout = Timeout(5 minutes)
  val future = worker ? 0
  val res = Await.result(future, 10 seconds)

According to the documentation, Await.result should throw the exception again, but what I am getting is a TimeoutException! Can someone clarify on this?

deepkimo
  • 3,187
  • 3
  • 23
  • 21

1 Answers1

15

For actors you need to catch the exception and return it as a failure status. Right now you're not returning anything to the sender so you're getting a timeout exception:

class Worker extends Actor {
  def receive = {
    case i: Int => {
      try {
        throw new RuntimeException
        sender ! "Some good result"
      } catch {
        case e: Exception =>
          sender ! akka.actor.Status.Failure(e) // Alert the sender of the failure
          throw e // Alert any supervisor actor of the failure
      }
    }
  }
}

Futures can handle this a little more gracefully since they always send a result, while actors do not (this would give you the same result as above):

  val future = Future {
    throw new RuntimeException
  }
Noah
  • 13,821
  • 4
  • 36
  • 45
  • Thanks for the clarification. The link you provided is also good in clarifying the interaction between actors and futures. I wonder, based on your understanding, do you find my above reference on futures accurate enough in clarifying this relation? – deepkimo Apr 19 '13 at 23:13
  • No, I wish the documentation was better. The problem is that actors aren't assumed to return anything to the sender, so you never know if an ask should complete. It would be nice if this was documented better, or if asks were just eliminated and a fully typed send receive actor mechanism was implemented. The ambiguity in untyped actors is only made worse by the ambiguity of untyped and completely unknown response possibilities. – Noah Apr 20 '13 at 02:34
  • Is this necessary? `throw e // Alert any supervisor actor of the failure`. Suppose the error is due to "incorrect password" for a login actor. Would throw help the supervisor? – Jus12 Mar 28 '17 at 21:10
  • @Jus12 depends on your use case; in the case you describe, and indeed probably in most cases, the supervisor is unlikely to want to see that failure. I think Noah was just illustrating how you can do it if you need to and pointing out that it won't happen by default. – Giftiger Wunsch Mar 07 '18 at 12:01