diff --git a/traits/tests/test_listeners.py b/traits/tests/test_listeners.py index 66e3a8d7c..36e2ee69a 100644 --- a/traits/tests/test_listeners.py +++ b/traits/tests/test_listeners.py @@ -75,6 +75,11 @@ def alt_weight_changed(self, object, name, old, new): events["alt_weight_changed"] = (name, old, new) +class GenerateFailingEvents(HasTraits): + name = Str + def _name_changed(self): + raise RuntimeError + class Test_Listeners(unittest.TestCase): def test(self): @@ -124,6 +129,24 @@ def test(self): ge.trait_set(name='Ralph', age=29, weight=198.0) self.assertEqual(events, {}) + def test_trait_exception_handler_can_access_exception(self): + """ Tests if trait exception handlers can access the traceback of the exception. + """ + import traceback + + from traits import trait_notifiers + def _handle_exception(obj,name,old,new): + self.assertIsNotNone(sys.exc_info()[0]) + ge = GenerateFailingEvents() + try: + trait_notifiers.push_exception_handler( + _handle_exception, + reraise_exceptions=False, + main=True + ) + ge.trait_set(name='John Cleese') + finally: + trait_notifiers.pop_exception_handler() class A(HasTraits): exception = Any diff --git a/traits/trait_notifiers.py b/traits/trait_notifiers.py index 5b3285915..e3f1600db 100644 --- a/traits/trait_notifiers.py +++ b/traits/trait_notifiers.py @@ -339,17 +339,16 @@ def __call__ ( self, object, trait_name, old, new ): # Call the handler. self.handler( *args ) except Exception as e: - exception = e - else: - exception = None - finally: if _post_change_event_tracer is not None: _post_change_event_tracer( object, trait_name, old, new, self.handler, - exception=exception ) - - if exception is not None: + exception=e ) handle_exception( object, trait_name, old, new ) + else: + if _post_change_event_tracer is not None: + _post_change_event_tracer( object, trait_name, old, new, + self.handler, + exception=None ) def equals ( self, handler ): return False