improve error messages when attached modules fail on startup

Change-Id: Ic1d2d77de2574043749ddbc00def48a6fe77b2bd
This commit is contained in:
2025-10-27 13:04:21 +01:00
parent ea5fc16a51
commit 7adb4d6f04
2 changed files with 41 additions and 26 deletions

View File

@@ -342,6 +342,7 @@ class Module(HasAccessibles):
self.attachedModules = {}
self.errors = []
self._isinitialized = False
self._initfailed = False
self.updateCallback = srv.dispatcher.announce_update
# handle module properties
@@ -612,6 +613,7 @@ class Module(HasAccessibles):
"""
# we do not need self.errors any longer. should we delete it?
# del self.errors
self.polledModules = [m for m in self.polledModules if not m._initfailed]
if self.polledModules:
self.__poller = mkthread(self.__pollThread, self.polledModules, start_events.get_trigger())
self.startModuleDone = True
@@ -723,8 +725,10 @@ class Module(HasAccessibles):
rfunc = getattr(mobj, 'read_' + pname)
if rfunc.poll:
pinfo.polled_parameters.append((mobj, rfunc, pobj))
while True:
try:
for mobj in list(self.modules):
if mobj._initfailed:
modules.remove(mobj)
for mobj in modules:
# TODO when needed: here we might add a call to a method :meth:`beforeWriteInit`
mobj.writeInitParams()
@@ -734,7 +738,6 @@ class Module(HasAccessibles):
for mobj, rfunc, _ in m.pollInfo.polled_parameters:
mobj.callPollFunc(rfunc, raise_com_failed=True)
# TODO when needed: here we might add calls to a method :meth:`afterInitPolls`
break
except CommunicationFailedError as e:
# when communication failed, probably all parameters and may be more modules are affected.
# as this would take a lot of time (summed up timeouts), we do not continue
@@ -743,8 +746,6 @@ class Module(HasAccessibles):
self.log.error('communication failure on startup: %s', e)
started_callback()
started_callback = None
self.triggerPoll.wait(0.1) # wait for reconnection or max 10 sec.
break
if started_callback:
started_callback()
if not polled_modules: # no polls needed - exit thread

View File

@@ -30,6 +30,10 @@ from frappy.version import get_version
from frappy.modules import Module
class InitFailed(Exception):
pass
class SecNode:
"""Managing the modules.
@@ -85,11 +89,15 @@ class SecNode:
if not modobj.initModuleDone:
self.errors.append(f'{modobj.initModule.__qualname__} was not '
f'called, probably missing super call')
except InitFailed:
raise
except Exception as e:
if self.traceback_counter == 0:
self.log.exception(traceback.format_exc())
self.traceback_counter += 1
self.errors.append(f'error initializing {modulename}: {e!r}')
modobj._initfailed = True
raise InitFailed('try to access erroneous module')
modobj._isinitialized = True
self.log.debug('initialized module %r', modulename)
return modobj
@@ -101,8 +109,11 @@ class SecNode:
When creating a new module, srv.module_config is accessed to get the
modules configuration.
"""
if modulename in self.modules:
return self.modules[modulename]
modobj = self.modules.get(modulename)
if modobj:
if modobj._initfailed:
raise InitFailed('try to access erroneous module')
return modobj
if modulename in list(self.modules.values()):
# it's actually already the module object
return modulename
@@ -205,8 +216,11 @@ class SecNode:
def build_descriptive_data(self):
modules = {}
result = {'modules': modules}
for modulename in self.modules:
for modulename in list(self.modules):
try:
modobj = self.get_module(modulename)
except InitFailed:
continue
if not modobj.export:
continue
# some of these need rework !