From 2339e855bbbaa217cd24a87b53996811fab899e0 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 16 Oct 2020 16:00:24 +0200 Subject: [PATCH] *: Improve MonitoredTasks' error capture --- passbook/admin/tasks.py | 2 +- passbook/lib/tasks.py | 9 +++++++-- passbook/outposts/tasks.py | 2 +- passbook/sources/ldap/tasks.py | 2 +- passbook/stages/email/tasks.py | 2 +- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/passbook/admin/tasks.py b/passbook/admin/tasks.py index a0551eb3a..4c9532a4c 100644 --- a/passbook/admin/tasks.py +++ b/passbook/admin/tasks.py @@ -27,4 +27,4 @@ def update_latest_version(self: MonitoredTask): ) except (RequestException, IndexError) as exc: cache.set(VERSION_CACHE_KEY, "0.0.0", VERSION_CACHE_TIMEOUT) - self.set_status(TaskResult(TaskResultStatus.ERROR, [str(exc)])) + self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc)) diff --git a/passbook/lib/tasks.py b/passbook/lib/tasks.py index 0e837c559..55d1aed6f 100644 --- a/passbook/lib/tasks.py +++ b/passbook/lib/tasks.py @@ -2,6 +2,7 @@ from dataclasses import dataclass, field from datetime import datetime from enum import Enum +from traceback import format_tb from typing import Any, Dict, List, Optional from celery import Task @@ -25,11 +26,15 @@ class TaskResult: messages: List[str] = field(default_factory=list) - error: Optional[Exception] = field(default=None) - # Optional UID used in cache for tasks that run in different instances uid: Optional[str] = field(default=None) + def with_error(self, exc: Exception) -> "TaskResult": + """Since errors might not always be pickle-able, set the traceback""" + self.messages.extend(format_tb(exc.__traceback__)) + self.messages.append(str(exc)) + return self + @dataclass class TaskInfo: diff --git a/passbook/outposts/tasks.py b/passbook/outposts/tasks.py index 7b81f8e52..b4a3cd5df 100644 --- a/passbook/outposts/tasks.py +++ b/passbook/outposts/tasks.py @@ -45,7 +45,7 @@ def outpost_controller(self: MonitoredTask, outpost_pk: str): logs = ProxyDockerController(outpost).run_with_logs() except ControllerException as exc: self.set_status( - TaskResult(TaskResultStatus.ERROR, [str(exc)], exc, uid=outpost.name) + TaskResult(TaskResultStatus.ERROR, uid=outpost.name).with_error(exc) ) else: self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, logs, uid=outpost.name)) diff --git a/passbook/sources/ldap/tasks.py b/passbook/sources/ldap/tasks.py index 3652f901d..eb5ddfd2e 100644 --- a/passbook/sources/ldap/tasks.py +++ b/passbook/sources/ldap/tasks.py @@ -35,4 +35,4 @@ def ldap_sync(self: MonitoredTask, source_pk: int): ) ) except LDAPException as exc: - self.set_status(TaskResult(TaskResultStatus.ERROR, [str(exc)], exc)) + self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc)) diff --git a/passbook/stages/email/tasks.py b/passbook/stages/email/tasks.py index 89a2ce813..87c8a2f69 100644 --- a/passbook/stages/email/tasks.py +++ b/passbook/stages/email/tasks.py @@ -62,5 +62,5 @@ def send_mail(self: MonitoredTask, email_stage_pk: int, message: Dict[Any, Any]) ) ) except (SMTPException, ConnectionError) as exc: - self.set_status(TaskResult(TaskResultStatus.ERROR, [str(exc)], exc)) + self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc)) raise exc