Commit 3de19e8d authored by Martin Matějek's avatar Martin Matějek

Wrap IO operations with try/except

Fix race condition in file existence check and loading
parent db25b227
......@@ -49,16 +49,17 @@ class Notification:
try:
with open(path, 'r') as f:
json_data = json.load(f)
except FileNotFoundError:
logger.warning("Failed to open notification file '%s'", path)
return None
except json.JSONDecodeError as e:
logger.warning("Failed to deserialize json file: %s", e)
return None
skel_obj = NotificationSkeleton(**json_data['skeleton'])
json_data['skeleton'] = skel_obj # replace json data with skeleton instance
return cls(**json_data)
skel_obj = NotificationSkeleton(**json_data['skeleton'])
json_data['skeleton'] = skel_obj # replace json data with skeleton instance
# TODO: exception handling
except Exception as e:
# TODO: proper logging per exception
logger.warning("Failed to deserialize json file: %s", e)
return cls(**json_data)
def is_valid(self, timestamp=None):
"""If notification is still valid based on multiple conditions"""
......
......@@ -40,9 +40,12 @@ class NotificationStorage:
# save to disk
file_path = os.path.join(storage_dir, "{}.json".format(n.notif_id))
# TODO: try/catch
with open(file_path, 'w') as f:
f.write(json_data)
try:
with open(file_path, 'w') as f:
f.write(json_data)
except OSError:
logger.error("Error during writing notification to disk!")
def load(self, storage_dir):
"""Deserialize all notifications from FS"""
......@@ -53,7 +56,9 @@ class NotificationStorage:
logger.debug("File %s", filepath)
n = Notification.from_file(filepath)
self.notifications[n.notif_id] = n
if n:
self.notifications[n.notif_id] = n
def get(self, msgid):
"""Return single notification instance"""
......
......@@ -23,14 +23,19 @@ class Plugin:
@classmethod
def from_file(cls, filename):
with open(filename, 'r') as f:
data = yaml.load(f)
try:
with open(filename, 'r') as f:
data = yaml.load(f)
except FileNotFoundError:
logger.warning("Failed to open plugin file '%s'", filename)
return None
except yaml.YAMLError:
logger.warning("Failed to deserialize yaml file '%s'", filename)
return None
# TODO: better filename spliting handling
name = filename.split('.')[0].split('/')[-1]
# print("YML data {}".format(data))
return cls(name, **data)
def get_actions(self):
......
......@@ -30,7 +30,9 @@ class PluginStorage:
continue
p = Plugin.from_file(self.plugin_file_path(f))
self.plugins[p.name] = p
if p:
self.plugins[p.name] = p
def get_plugin(self, name):
"""Return plugin specified by name"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment