2
votes

I am migrating a project from scala actors to akka actors. I used to have something like this where the constructor of MyActor may throw an exception if a certain system resource is unavailable:

var myActor: MyActor = null
try {
  myActor = new MyActor(3)
}
catch {
  case e: SomeUserDefinedException => println("failed!")
}

With akka, I migrated the code to this:

val someParam = 3
var myActor: ActorRef = null
try {
  myActor = context.actorOf(Props(classOf[MyActor], someParam), "myActor")
}
catch {
  case e: SomeUserDefinedException => println("failed!")
}

The problem I'm having is that it seems like in the akka case, the context.actorOf call isn't actually creating the MyActor object itself, but deferring it to another thread. So when the constructor throws an exception, the try/catch block that I put in has no effect.

How can I migrate this scala actor code into akka actors? Ideally I would prefer to avoid adding a lot of additional complexity.

1
What exactly do you plan on doing when it fails? If all you want to do is print (which I doubt is the case), then I'm sure the actor failing will end up in your log anyway. How you want to react to this failure to start the actor will help me come up with the best possible solution(s) for you. - cmbaxter

1 Answers

2
votes

You can catch the exception in the constructor of MyActor and notify other actors (e.g. the parent) about this exception. Try this:

class MyActor(val parent: ActorRef) extends Actor {
  try{
    throw new RuntimeException("failed construct")
  } catch {
    case e: Throwable => 
        parent ! e
        throw e
  }

  def receive: Actor.Receive = {case _ => }
}

class ParentActor extends Actor {
  val child = context.actorOf(Props(classOf[MyActor], self), "child")
  override def receive = {
    case e: Throwable => println(e)
  }
}