diff --git a/qubesadmin/events/__init__.py b/qubesadmin/events/__init__.py index c1a37286..0bea5cc3 100644 --- a/qubesadmin/events/__init__.py +++ b/qubesadmin/events/__init__.py @@ -249,4 +249,9 @@ def handle(self, subject, event, **kwargs): for h_func in h_func_set if fnmatch.fnmatch(event, h_name)] for handler in handlers: - handler(subject, event, **kwargs) + try: + handler(subject, event, **kwargs) + except: # pylint: disable=bare-except + self.app.log.exception( + 'Failed to handle event: %s, %s, %s', + subject, event, kwargs) diff --git a/qubesadmin/tests/events.py b/qubesadmin/tests/events.py index 62ca6237..5510ca91 100644 --- a/qubesadmin/tests/events.py +++ b/qubesadmin/tests/events.py @@ -90,6 +90,16 @@ def test_002_handler_glob_partial(self): self.dispatcher.handle('', 'some-event', arg1='value1') self.assertFalse(handler.called) + def test_003_handler_error(self): + handler = unittest.mock.Mock() + self.dispatcher.add_handler('some-event', handler) + handler2 = unittest.mock.Mock(side_effect=AssertionError) + self.dispatcher.add_handler('some-event', handler2) + # should catch the exception + self.dispatcher.handle('', 'some-event', arg1='value1') + handler.assert_called_once_with(None, 'some-event', arg1='value1') + handler2.assert_called_once_with(None, 'some-event', arg1='value1') + async def mock_get_events_reader(self, stream, cleanup_func, expected_vm, vm=None): self.assertEqual(expected_vm, vm)