summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2010-04-13 11:37:42 +0000
committerPhilipp Haller <hallerp@gmail.com>2010-04-13 11:37:42 +0000
commitaad801fc89b24843497963b14b6c96ed1ce77c06 (patch)
treedc6a2effbb06a54366d7e0b8a07275c8e6315406
parentea91456310736caed3064c117c5a72f515d59688 (diff)
downloadscala-aad801fc89b24843497963b14b6c96ed1ce77c06.tar.gz
scala-aad801fc89b24843497963b14b6c96ed1ce77c06.tar.bz2
scala-aad801fc89b24843497963b14b6c96ed1ce77c06.zip
Improved handling of uncaught exceptions in act...
Improved handling of uncaught exceptions in actors. See #711. Review by community.
-rw-r--r--src/actors/scala/actors/ActorTask.scala2
-rw-r--r--src/actors/scala/actors/IScheduler.scala19
-rw-r--r--src/actors/scala/actors/ReactorTask.scala13
-rw-r--r--src/actors/scala/actors/UncaughtException.scala2
4 files changed, 25 insertions, 11 deletions
diff --git a/src/actors/scala/actors/ActorTask.scala b/src/actors/scala/actors/ActorTask.scala
index 2fa24f93af..6757a69a43 100644
--- a/src/actors/scala/actors/ActorTask.scala
+++ b/src/actors/scala/actors/ActorTask.scala
@@ -29,7 +29,7 @@ private[actors] class ActorTask(actor: Actor,
actor.exit()
}
- protected override def terminateExecution(e: Exception) {
+ protected override def terminateExecution(e: Throwable) {
val senderInfo = try { Some(actor.sender) } catch {
case _: Exception => None
}
diff --git a/src/actors/scala/actors/IScheduler.scala b/src/actors/scala/actors/IScheduler.scala
index 1718dab045..f65aa020f8 100644
--- a/src/actors/scala/actors/IScheduler.scala
+++ b/src/actors/scala/actors/IScheduler.scala
@@ -68,6 +68,25 @@ trait IScheduler {
def managedBlock(blocker: scala.concurrent.ManagedBlocker): Unit
+ /** This method is called when an exception is not handled by
+ * some reactor while processing a certain message.
+ *
+ * @param t the unhandled exception
+ * @param reactor the reactor inside which the exception was thrown
+ * @param msg the message last removed from the reactor's mailbox
+ */
+ def handleUncaughtThrowable[Msg >: Null](t: Throwable, reactor: Reactor[Msg], msg: Msg) {
+ // print message on default error stream
+ val msgException = "Uncaught exception in "+reactor+"\n"
+ val msgMessage = if (msg != null) "Message: "+msg+"\n" else ""
+ Debug.doWarning {
+ Console.err.print(msgException + msgMessage)
+ t.printStackTrace()
+ }
+ if (t.isInstanceOf[Error])
+ throw t
+ }
+
@deprecated("this member is going to be removed in a future release")
def tick(a: Actor) {}
diff --git a/src/actors/scala/actors/ReactorTask.scala b/src/actors/scala/actors/ReactorTask.scala
index 3f9ebb6fa7..2e25459c9d 100644
--- a/src/actors/scala/actors/ReactorTask.scala
+++ b/src/actors/scala/actors/ReactorTask.scala
@@ -49,14 +49,9 @@ private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
case _: SuspendActorControl =>
// do nothing (continuation is already saved)
- case e: Exception =>
- // print message on default error stream
- val msgException = "Uncaught exception in "+reactor+"\n"
- val msgMessage = if (msg != null) "Message: "+msg+"\n" else ""
- Debug.doWarning {
- Console.err.print(msgException + msgMessage)
- e.printStackTrace()
- }
+ case e: Throwable =>
+ // re-throws `Error`s by default
+ reactor.scheduler.handleUncaughtThrowable(e, reactor, msg)
terminateExecution(e)
reactor.terminated()
@@ -77,6 +72,6 @@ private[actors] class ReactorTask[Msg >: Null](var reactor: Reactor[Msg],
protected def suspendExecution() {}
- protected def terminateExecution(e: Exception) {}
+ protected def terminateExecution(e: Throwable) {}
}
diff --git a/src/actors/scala/actors/UncaughtException.scala b/src/actors/scala/actors/UncaughtException.scala
index 54c28f66cf..1829d48606 100644
--- a/src/actors/scala/actors/UncaughtException.scala
+++ b/src/actors/scala/actors/UncaughtException.scala
@@ -23,7 +23,7 @@ class UncaughtException[Msg >: Null](val actor: Reactor[Msg],
val message: Option[Msg],
val sender: Option[OutputChannel[Any]],
val thread: Thread,
- cause: Exception)
+ cause: Throwable)
extends Exception(cause) {
override def toString() =