3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 01:09:22 +01:00

Don't crash when REHASH loads a config file that's invalid

This was actually several bugs in one:
- The sys.exit() call in loadConf should be... toggleable
- loadConf printed errors but forgot to re-raise the actual exception it caught
- The error reply in the REHASH command was passing the wrong arguments to irc.reply(), which would cause an error within an error when it ran
This commit is contained in:
James Lu 2015-11-11 18:55:51 -08:00
parent 2008df047c
commit 5027feb553
2 changed files with 29 additions and 24 deletions

View File

@ -47,15 +47,18 @@ def validateConf(conf):
conf['login']['password'] != "changeme", "You have not set the login details correctly!" conf['login']['password'] != "changeme", "You have not set the login details correctly!"
return conf return conf
def loadConf(fname): def loadConf(fname, errors_fatal=True):
"""Loads a PyLink configuration file from the filename given.""" """Loads a PyLink configuration file from the filename given."""
with open(fname, 'r') as f: with open(fname, 'r') as f:
try: try:
conf = yaml.load(f) conf = yaml.load(f)
except Exception as e: except Exception as e:
print('ERROR: Failed to load config from %r: %s: %s' % (fname, type(e).__name__, e)) print('ERROR: Failed to load config from %r: %s: %s' % (fname, type(e).__name__, e))
sys.exit(4) if errors_fatal:
return conf sys.exit(4)
raise
else:
return conf
if world.testing: if world.testing:
conf = testconf conf = testconf

View File

@ -175,30 +175,32 @@ def rehash(irc, source, args):
old_conf = conf.conf.copy() old_conf = conf.conf.copy()
fname = conf.fname fname = conf.fname
try: try:
new_conf = conf.validateConf(conf.loadConf(fname)) new_conf = conf.loadConf(fname, errors_fatal=False)
except Exception as e: # Something went wrong, abort. except Exception as e: # Something went wrong, abort.
log.exception("Error REHASH'ing config: ") log.exception("Error REHASH'ing config: ")
irc.reply("Error loading configuration file: %s: %s", type(e).__name__, e) irc.reply("Error loading configuration file: %s: %s" % (type(e).__name__, e))
return return
conf.conf = new_conf else:
for network, ircobj in world.networkobjects.copy().items(): new_conf = conf.validateConf(new_conf)
# Server was removed from the config file, disconnect them. conf.conf = new_conf
log.debug('(%s) rehash: checking if %r is in new conf still.', irc.name, network) for network, ircobj in world.networkobjects.copy().items():
if network not in new_conf['servers']: # Server was removed from the config file, disconnect them.
# Disable autoconnect first. log.debug('(%s) rehash: checking if %r is in new conf still.', irc.name, network)
log.debug('(%s) rehash: removing connection to %r (removed from config).', irc.name, network) if network not in new_conf['servers']:
ircobj.serverdata['autoconnect'] = -1 log.debug('(%s) rehash: removing connection to %r (removed from config).', irc.name, network)
ircobj.aborted.set() # Disable autoconnect first.
del world.networkobjects[network] ircobj.serverdata['autoconnect'] = -1
else: ircobj.aborted.set()
ircobj.conf = new_conf del world.networkobjects[network]
ircobj.serverdata = new_conf['servers'][network] else:
for network, sdata in new_conf['servers'].items(): ircobj.conf = new_conf
# New server was added. Connect them if not already connected. ircobj.serverdata = new_conf['servers'][network]
if network not in world.networkobjects: for network, sdata in new_conf['servers'].items():
proto = utils.getProtoModule(sdata['protocol']) # New server was added. Connect them if not already connected.
world.networkobjects[network] = classes.Irc(network, proto, new_conf) if network not in world.networkobjects:
irc.reply("Done.") proto = utils.getProtoModule(sdata['protocol'])
world.networkobjects[network] = classes.Irc(network, proto, new_conf)
irc.reply("Done.")
loglevels = {'DEBUG': 10, 'INFO': 20, 'WARNING': 30, 'ERROR': 40, 'CRITICAL': 50} loglevels = {'DEBUG': 10, 'INFO': 20, 'WARNING': 30, 'ERROR': 40, 'CRITICAL': 50}
@utils.add_cmd @utils.add_cmd