diff options
author | Trygve Aaberge <trygveaa@gmail.com> | 2023-01-31 20:05:17 +0100 |
---|---|---|
committer | Trygve Aaberge <trygveaa@gmail.com> | 2024-02-18 11:32:53 +0100 |
commit | 8805a2398e4a273ba22c172b3fc1254028834de2 (patch) | |
tree | c920fd40ad5a3b4e7aef87c2b398db8e53061190 /slack | |
parent | bfa38ba5ee0a7a4387eddc30feb1e3ad2e1aab78 (diff) | |
download | wee-slack-8805a2398e4a273ba22c172b3fc1254028834de2.tar.gz |
Log failed async tasks more robustly
Diffstat (limited to 'slack')
-rw-r--r-- | slack/commands.py | 6 | ||||
-rw-r--r-- | slack/register.py | 8 | ||||
-rw-r--r-- | slack/slack_workspace.py | 4 | ||||
-rw-r--r-- | slack/task.py | 39 |
4 files changed, 22 insertions, 35 deletions
diff --git a/slack/commands.py b/slack/commands.py index cd25456..f0bf941 100644 --- a/slack/commands.py +++ b/slack/commands.py @@ -17,7 +17,7 @@ from slack.slack_conversation import ( ) from slack.slack_user import name_from_user_info_without_spaces from slack.slack_workspace import SlackWorkspace -from slack.task import create_task +from slack.task import run_async from slack.util import get_callback_name, with_color from slack.weechat_config import WeeChatOption, WeeChatOptionTypes @@ -127,7 +127,7 @@ def command_slack_connect( for workspace in shared.workspaces.values(): await workspace.connect() - create_task(connect()) + run_async(connect()) @weechat_command("%(slack_workspaces)|-all") @@ -414,7 +414,7 @@ def input_complete_cb(data: str, buffer: str, command: str) -> int: is_first_word = word_until_cursor == input_before_cursor if command == "/input complete_next": - create_task(complete_user_next(conversation, query, is_first_word)) + run_async(complete_user_next(conversation, query, is_first_word)) return weechat.WEECHAT_RC_OK_EAT else: return complete_previous(conversation, query) diff --git a/slack/register.py b/slack/register.py index 38a9a35..f403ac3 100644 --- a/slack/register.py +++ b/slack/register.py @@ -6,7 +6,7 @@ from slack.commands import register_commands from slack.config import SlackConfig from slack.shared import shared from slack.slack_conversation import get_conversation_from_buffer_pointer -from slack.task import create_task, sleep +from slack.task import run_async, sleep from slack.util import get_callback_name, with_color SCRIPT_AUTHOR = "Trygve Aaberge <trygveaa@gmail.com>" @@ -23,7 +23,7 @@ def shutdown_cb(): def signal_buffer_switch_cb(data: str, signal: str, buffer_pointer: str) -> int: conversation = get_conversation_from_buffer_pointer(buffer_pointer) if conversation: - create_task(conversation.fill_history()) + run_async(conversation.fill_history()) return weechat.WEECHAT_RC_OK @@ -82,7 +82,7 @@ async def init_async(): await sleep(1) # Defer auto connect to ensure the logger plugin is loaded for workspace in shared.workspaces.values(): if workspace.config.autoconnect.value: - create_task(workspace.connect()) + run_async(workspace.connect()) def register(): @@ -120,4 +120,4 @@ def register(): ) weechat.hook_timer(5000, 0, 0, get_callback_name(ws_ping_cb), "") - create_task(init_async()) + run_async(init_async()) diff --git a/slack/slack_workspace.py b/slack/slack_workspace.py index 243dfd1..bc31a27 100644 --- a/slack/slack_workspace.py +++ b/slack/slack_workspace.py @@ -21,7 +21,7 @@ from slack.shared import shared from slack.slack_api import SlackApi from slack.slack_conversation import SlackConversation from slack.slack_user import SlackBot, SlackUser, SlackUsergroup -from slack.task import Future, Task, create_task, gather +from slack.task import Future, Task, create_task, gather, run_async from slack.util import get_callback_name if TYPE_CHECKING: @@ -199,7 +199,7 @@ class SlackWorkspace: await self.conversations.initialize_items(channel["id"] for channel in channels) for channel in channels: conversation = await self.conversations[channel["id"]] - create_task(conversation.open_if_open()) + run_async(conversation.open_if_open()) self.is_connected = True diff --git a/slack/task.py b/slack/task.py index 9dfc817..4899741 100644 --- a/slack/task.py +++ b/slack/task.py @@ -1,6 +1,5 @@ from __future__ import annotations -import traceback from typing import ( TYPE_CHECKING, Any, @@ -21,7 +20,7 @@ from uuid import uuid4 import weechat -from slack.error import HttpError, SlackApiError, SlackError, format_exception +from slack.error import format_exception from slack.log import print_error from slack.shared import shared from slack.util import get_callback_name @@ -193,31 +192,7 @@ def task_runner(task: Task[Any], response: object): future = task.coroutine.send(response) except BaseException as e: result = e.value if isinstance(e, StopIteration) else e - in_active_tasks = task.id in shared.active_tasks process_ended_task(task, result) - - if isinstance(result, BaseException): - weechat_task_cb_in_stack = "weechat_task_cb" in [ - stack.name for stack in traceback.extract_stack() - ] - create_task_in_stack = [ - stack.name for stack in traceback.extract_stack() - ].count("create_task") - if not in_active_tasks and ( - create_task_in_stack == 0 - or not weechat_task_cb_in_stack - and create_task_in_stack == 1 - ): - if ( - isinstance(e, HttpError) - or isinstance(e, SlackApiError) - or isinstance(e, SlackError) - ): - exception_str = format_exception(e) - print_error(f"{exception_str}, task: {task}") - else: - raise e - return if future.done(): @@ -234,6 +209,18 @@ def create_task(coroutine: Coroutine[Future[Any], Any, T]) -> Task[T]: return task +def _async_task_done(task: Task[object]): + exception = task.exception() + if exception: + print_error(f"{task} failed with: {format_exception(exception)}") + + +def run_async(coroutine: Coroutine[Future[Any], Any, Any]) -> None: + task = Task(coroutine) + task.add_done_callback(_async_task_done) + task_runner(task, None) + + @overload async def gather( *requests: Union[Future[T], Coroutine[Any, Any, T]], |