diff options
author | Steven Knight <knight@baldmt.com> | 2003-03-03 06:28:49 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-03-03 06:28:49 (GMT) |
commit | bc08cde50aee2b6a495506819b97014fdb880058 (patch) | |
tree | b1fbe65c9b6724de14ba2415d873b5cbe8bcc6a4 /src/engine | |
parent | b2955d7ab85b8aaa5a1f2c18e8e4329a43981a34 (diff) | |
download | SCons-bc08cde50aee2b6a495506819b97014fdb880058.zip SCons-bc08cde50aee2b6a495506819b97014fdb880058.tar.gz SCons-bc08cde50aee2b6a495506819b97014fdb880058.tar.bz2 |
Don't eat scanner exceptions.
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/SCons/Script/__init__.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Taskmaster.py | 39 | ||||
-rw-r--r-- | src/engine/SCons/TaskmasterTests.py | 45 |
3 files changed, 67 insertions, 19 deletions
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 3716d2e..b14e50d 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -143,6 +143,8 @@ class BuildTask(SCons.Taskmaster.Task): s = s + ' Stop.' sys.stderr.write("scons: *** %s\n" % s) else: + if e is None: + e = sys.exc_type sys.stderr.write("scons: *** %s\n" % e) self.do_failed() diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 521dc19..68e251c 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -73,13 +73,12 @@ class Task: This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in prepare(), executed() or failed().""" - try: - # We recorded an exception while getting this Task ready - # for execution. Raise it now. - raise self.node.exc_type, self.node.exc_value - except AttributeError: - # The normal case: no exception to raise. - pass + + # Now that it's the appropriate time, give the TaskMaster a + # chance to raise any exceptions it encountered while preparing + # this task. + self.tm.exception_raise() + try: self.targets[0].build() except KeyboardInterrupt: @@ -194,6 +193,7 @@ class Taskmaster: self.ready = None # the next task that is ready to be executed self.calc = calc self.order = order + self.exception_set(None, None) def _find_next_ready_node(self): """Find the next node that is ready to be built""" @@ -218,10 +218,9 @@ class Taskmaster: except: # We had a problem just trying to figure out the # children (like a child couldn't be linked in to a - # BuildDir). Arrange to raise the exception when the - # Task is "executed." - node.exc_type = sys.exc_type - node.exc_value = sys.exc_value + # BuildDir, or a Scanner threw something). Arrange to + # raise the exception when the Task is "executed." + self.exception_set(sys.exc_type, sys.exc_value) self.candidates.pop() self.ready = node break @@ -296,8 +295,7 @@ class Taskmaster: # a child couldn't be linked in to a BuildDir when deciding # whether this node is current). Arrange to raise the # exception when the Task is "executed." - node.exc_type = sys.exc_type - node.exc_value = sys.exc_value + self.exception_set(sys.exc_type, sys.exc_value) self.ready = None return task @@ -332,3 +330,18 @@ class Taskmaster: self.candidates.extend(self.pending) self.pending = [] + def exception_set(self, type, value): + """Record an exception type and value to raise later, at an + appropriate time.""" + self.exc_type = type + self.exc_value = value + + def exception_raise(self): + """Raise any pending exception that was recorded while + getting a Task ready for execution.""" + if self.exc_type: + try: + raise self.exc_type, self.exc_value + finally: + self.exception_set(None, None) + diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 5a19c56..2f9383a 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -385,8 +385,8 @@ class TaskmasterTestCase(unittest.TestCase): n1 = Node("n1") tm = SCons.Taskmaster.Taskmaster(targets = [n1], tasker = MyTask) t = tm.next_task() - assert n1.exc_type == MyException, n1.exc_type - assert str(n1.exc_value) == "from make_ready()", n1.exc_value + assert tm.exc_type == MyException, tm.exc_type + assert str(tm.exc_value) == "from make_ready()", tm.exc_value def test_children_errors(self): @@ -398,8 +398,8 @@ class TaskmasterTestCase(unittest.TestCase): n1 = MyNode("n1") tm = SCons.Taskmaster.Taskmaster([n1]) t = tm.next_task() - assert n1.exc_type == SCons.Errors.StopError, "Did not record StopError on node" - assert str(n1.exc_value) == "stop!", "Unexpected exc_value `%s'" % n1.exc_value + assert tm.exc_type == SCons.Errors.StopError, "Did not record StopError on node" + assert str(tm.exc_value) == "stop!", "Unexpected exc_value `%s'" % tm.exc_value def test_cycle_detection(self): """Test detecting dependency cycles @@ -590,9 +590,9 @@ class TaskmasterTestCase(unittest.TestCase): built_text = None n5 = Node("n5") - n5.exc_type = MyException - n5.exc_value = "exception value" tm = SCons.Taskmaster.Taskmaster([n5]) + tm.exc_type = MyException + tm.exc_value = "exception value" t = tm.next_task() exc_caught = None try: @@ -603,6 +603,39 @@ class TaskmasterTestCase(unittest.TestCase): assert exc_caught, "did not catch expected MyException" assert built_text is None, built_text + def test_exception(self): + """Test generic Taskmaster exception handling + + """ + n1 = Node("n1") + tm = SCons.Taskmaster.Taskmaster([n1]) + + tm.exception_set(1, 2) + assert tm.exc_type == 1, tm.exc_type + assert tm.exc_value == 2, tm.exc_value + + tm.exception_set(None, None) + assert tm.exc_type is None, tm.exc_type + assert tm.exc_value is None, tm.exc_value + + tm.exception_set("exception 1", None) + try: + tm.exception_raise() + except: + assert sys.exc_type == "exception 1", sys.exc_type + assert sys.exc_value is None, sys.exc_type + else: + assert 0, "did not catch expected exception" + + tm.exception_set("exception 2", "xyzzy") + try: + tm.exception_raise() + except: + assert sys.exc_type == "exception 2", sys.exc_type + assert sys.exc_value == "xyzzy", sys.exc_type + else: + assert 0, "did not catch expected exception" + if __name__ == "__main__": |