From 8b59ddb0c98022d57317b49069f773ef3b61181b Mon Sep 17 00:00:00 2001 From: deadzilla Date: Wed, 22 Jul 2026 22:28:13 +0500 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20add=5Fdone=5Fcallback=20=D0=B2=20Scheduler.=5Fta?= =?UTF-8?q?sk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Если _scheduler_loop завершится с неожиданной ошибкой (не CancelledError), это теперь залогировано через _on_task_done callback. Штатное завершение через cancel() пропускается без логов. --- utils/morning_runner.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/utils/morning_runner.py b/utils/morning_runner.py index 77e78f5..17f6cf3 100644 --- a/utils/morning_runner.py +++ b/utils/morning_runner.py @@ -157,8 +157,21 @@ class Scheduler: return self._running = True self._task = asyncio.create_task(self._scheduler_loop()) + self._task.add_done_callback(self._on_task_done) logger.info("Планировщик запущен (время: %s)", self.morning_time) + def _on_task_done(self, task: asyncio.Task) -> None: + """Логировать нештатное завершение task. + + CancelledError — штатное завершение при stop(), поэтому пропускается. + Любое другое исключение — признак ошибки в _scheduler_loop. + """ + if task.cancelled(): + return + exc = task.exception() + if exc and not isinstance(exc, asyncio.CancelledError): + logger.error("Scheduler завершился с ошибкой: %s", exc) + def _stop_scheduler(self): if self._task and not self._task.done(): self._task.cancel()