diff --git a/akka-actor/src/main/scala/akka/actor/ActorCell.scala b/akka-actor/src/main/scala/akka/actor/ActorCell.scala index 1a25faaef0..a48d5c4c45 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorCell.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorCell.scala @@ -471,7 +471,13 @@ private[akka] class ActorCell( } } - protected def create(uid: Int): Unit = + protected def create(uid: Int): Unit = { + def clearOutActorIfNonNull(): Unit = { + if (actor != null) { + clearActorFields(actor) + actor = null // ensure that we know that we failed during creation + } + } try { this.uid = uid val created = newActor() @@ -480,11 +486,12 @@ private[akka] class ActorCell( checkReceiveTimeout if (system.settings.DebugLifecycle) publish(Debug(self.path.toString, clazz(created), "started (" + created + ")")) } catch { + case e: InterruptedException ⇒ + clearOutActorIfNonNull() + Thread.currentThread().interrupt() + throw ActorInitializationException(self, "interruption during creation", e) case NonFatal(e) ⇒ - if (actor != null) { - clearActorFields(actor) - actor = null // ensure that we know that we failed during creation - } + clearOutActorIfNonNull() e match { case i: InstantiationException ⇒ throw ActorInitializationException(self, """exception during creation, this problem is likely to occur because the class of the Actor you tried to create is either, @@ -494,6 +501,7 @@ private[akka] class ActorCell( case x ⇒ throw ActorInitializationException(self, "exception during creation", x) } } + } private def supervise(child: ActorRef, async: Boolean, uid: Int): Unit = if (!isTerminating) { diff --git a/akka-actor/src/main/scala/akka/actor/dungeon/Children.scala b/akka-actor/src/main/scala/akka/actor/dungeon/Children.scala index 22bcc9cd9e..9c64d79a64 100644 --- a/akka-actor/src/main/scala/akka/actor/dungeon/Children.scala +++ b/akka-actor/src/main/scala/akka/actor/dungeon/Children.scala @@ -185,10 +185,12 @@ private[akka] trait Children { this: ActorCell ⇒ cell.provider.actorOf(cell.systemImpl, props, cell.self, cell.self.path / name, systemService = systemService, deploy = None, lookupDeploy = true, async = async) } catch { - case e @ (_: InterruptedException | NonFatal(_)) ⇒ + case e: InterruptedException ⇒ + unreserveChild(name) + Thread.interrupted() // clear interrupted flag before throwing according to java convention + throw e + case NonFatal(e) ⇒ unreserveChild(name) - if (e.isInstanceOf[InterruptedException]) - Thread.interrupted() // clear interrupted flag before throwing according to java convention throw e } // mailbox==null during RoutedActorCell constructor, where suspends are queued otherwise diff --git a/akka-actor/src/main/scala/akka/actor/dungeon/FaultHandling.scala b/akka-actor/src/main/scala/akka/actor/dungeon/FaultHandling.scala index bc09fcc56f..053765296a 100644 --- a/akka-actor/src/main/scala/akka/actor/dungeon/FaultHandling.scala +++ b/akka-actor/src/main/scala/akka/actor/dungeon/FaultHandling.scala @@ -174,20 +174,16 @@ private[akka] trait FaultHandling { this: ActorCell ⇒ case _ ⇒ setFailed(self); Set.empty } suspendChildren(exceptFor = skip ++ childrenNotToSuspend) - // tell supervisor - t match { // Wrap InterruptedExceptions and, clear the flag and rethrow - case _: InterruptedException ⇒ - parent.tell(Failed(new ActorInterruptedException(t), uid), self) - Thread.interrupted() // clear interrupted flag before throwing according to java convention - throw t - case _ ⇒ parent.tell(Failed(t, uid), self) + t match { + // tell supervisor + case _: InterruptedException ⇒ parent.tell(Failed(new ActorInterruptedException(t), uid), self) + case _ ⇒ parent.tell(Failed(t, uid), self) } - } catch { - case NonFatal(e) ⇒ - publish(Error(e, self.path.toString, clazz(actor), - "emergency stop: exception in failure handling for " + t.getClass + Logging.stackTraceFor(t))) - try children foreach stop - finally finishTerminate() + } catch handleNonFatalOrInterruptedException { e ⇒ + publish(Error(e, self.path.toString, clazz(actor), + "emergency stop: exception in failure handling for " + t.getClass + Logging.stackTraceFor(t))) + try children foreach stop + finally finishTerminate() } }