diff --git a/supervisor/events.py b/supervisor/events.py index a9b0f181f..07d006ac6 100644 --- a/supervisor/events.py +++ b/supervisor/events.py @@ -174,6 +174,15 @@ def payload(self): class ProcessGroupAddedEvent(ProcessGroupEvent): pass +class AddProcessGroupFailedEvent(ProcessGroupEvent): + def __init__(self, group, err = None): + super().__init__(group) + self.err = err + + def payload(self): + payload = super().payload() + return payload+'error:%s\n' % self.err + class ProcessGroupRemovedEvent(ProcessGroupEvent): pass diff --git a/supervisor/supervisord.py b/supervisor/supervisord.py index 0a4f3e697..d0db700c3 100755 --- a/supervisor/supervisord.py +++ b/supervisor/supervisord.py @@ -114,7 +114,12 @@ def add_process_group(self, config): name = config.name if name not in self.process_groups: config.after_setuid() - self.process_groups[name] = config.make_group() + try: + self.process_groups[name] = config.make_group() + except BaseException as why: + self.options.logger.warn('Unable to add group %s: %s' % (name, why)) + events.notify(events.AddProcessGroupFailedEvent(name, why)) + return False events.notify(events.ProcessGroupAddedEvent(name)) return True return False diff --git a/supervisor/tests/test_supervisord.py b/supervisor/tests/test_supervisord.py index 4099bba6c..549a16a01 100644 --- a/supervisor/tests/test_supervisord.py +++ b/supervisor/tests/test_supervisord.py @@ -834,3 +834,19 @@ def callback(event): self.assertEqual(supervisord.ticks[3600], 3600) self.assertEqual(len(L), 6) self.assertEqual(L[-1].__class__, events.Tick3600Event) + + def test_add_failing_process_group_wont_crush(self): + options = DummyOptions() + supervisord = self._makeOne(options) + + pconfig = DummyPConfig(options, 'process1', '/bin/foo', '/tmp') + group = DummyPGroupConfig(options, 'group1', pconfigs=[pconfig]) + def throw(): + raise Exception() + group.make_group = throw + + # set up supervisord with an active configuration of group1 and group2 + supervisord.options.process_group_configs = [group] + self.assertFalse(supervisord.add_process_group(group)) + self.assertTrue(not supervisord.process_groups) + self.assertTrue(str(options.logger.data[0]).startswith('Unable to add group')) \ No newline at end of file