问题
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:
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)
}
}
来源:https://stackoverflow.com/questions/18648390/how-should-an-akka-actor-be-created-that-might-throw-an-exception