From 6eefa17f5addb8d507f70904640e182de6fe310b Mon Sep 17 00:00:00 2001 From: Thomas Oettli Date: Fri, 6 Nov 2020 16:46:24 +0100 Subject: [PATCH] improve error handling in FileManagerScheduler --- pyinotifyd/__init__.py | 20 +++++++++------ pyinotifyd/scheduler.py | 54 +++++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/pyinotifyd/__init__.py b/pyinotifyd/__init__.py index 376eb05..1778c30 100755 --- a/pyinotifyd/__init__.py +++ b/pyinotifyd/__init__.py @@ -117,6 +117,16 @@ class DaemonInstance: self._shutdown = True self._log.info(f"got signal {signame}, shutdown") self.stop() + + pending = self._get_pending_tasks() + for task in pending: + task.cancel() + + try: + await asyncio.gather(*pending) + except asyncio.CancelledError: + pass + pending = self._get_pending_tasks() if pending: tasks_done = False @@ -133,14 +143,8 @@ class DaemonInstance: future.exception() if not tasks_done: - self._log.warning("terminate remaining task(s)") - for task in pending: - task.cancel() - - try: - await asyncio.gather(*pending) - except asyncio.CancelledError: - pass + self._log.warning( + f"terminate {len(pending)} remaining task(s)") asyncio.get_event_loop().stop() self._shutdown = False diff --git a/pyinotifyd/scheduler.py b/pyinotifyd/scheduler.py index cc4ed0d..af9968d 100755 --- a/pyinotifyd/scheduler.py +++ b/pyinotifyd/scheduler.py @@ -302,12 +302,12 @@ class FileManagerScheduler(TaskScheduler): dst = rule.src_re.sub(rule.dst_re, path) if not dst: raise RuntimeError( - f"{task_id}: unable to {rule.action} '{path}', " + f"unable to {rule.action} '{path}', " f"resulting destination path is empty") if os.path.exists(dst): raise RuntimeError( - f"{task_id}: unable to move file from '{path} " + f"unable to move file from '{path} " f"to '{dst}', dstination path exists already") dst_dir = os.path.dirname(dst) @@ -321,35 +321,47 @@ class FileManagerScheduler(TaskScheduler): first_subdir = parent else: break - os.makedirs(dst_dir) - await asyncio.shield( - self._set_mode_and_owner(first_subdir, rule, task_id)) + + try: + os.makedirs(dst_dir) + await asyncio.shield( + self._set_mode_and_owner( + first_subdir, rule, task_id)) + except Exception as e: + raise RuntimeError(e) self._log.info( f"{task_id}: {rule.action} '{path}' to '{dst}'") - if rule.action == "copy": - if os.path.isdir(path): - shutil.copytree(path, dst) + + try: + if rule.action == "copy": + if os.path.isdir(path): + shutil.copytree(path, dst) + else: + shutil.copy2(path, dst) + else: - shutil.copy2(path, dst) + os.rename(path, dst) - else: - os.rename(path, dst) - - await asyncio.shield( - self._set_mode_and_owner(dst, rule, task_id)) + await asyncio.shield( + self._set_mode_and_owner(dst, rule, task_id)) + except Exception as e: + raise RuntimeError(e) elif rule.action == "delete": self._log.info( f"{task_id}: {rule.action} '{path}'") - if os.path.isdir(path): - if rule.rec: - shutil.rmtree(path) - else: - shutil.rmdir(path) + try: + if os.path.isdir(path): + if rule.rec: + shutil.rmtree(path) + else: + shutil.rmdir(path) - else: - os.remove(path) + else: + os.remove(path) + except Exception as e: + raise RuntimeError(e) except RuntimeError as e: self._log.error(f"{task_id}: {e}")