From a50990bef2f757d3e7eb2cdcbe55b3ebe6d5a7a6 Mon Sep 17 00:00:00 2001
From: Ju4tCode <42488585+yanyongyu@users.noreply.github.com>
Date: Tue, 15 Nov 2022 10:50:52 +0800
Subject: [PATCH] :bug: fix run pre/post hook not in context (#1391)
---
nonebot/internal/matcher.py | 66 +++++++++++++++++++++----------------
nonebot/message.py | 36 +++++++++++---------
2 files changed, 57 insertions(+), 45 deletions(-)
diff --git a/nonebot/internal/matcher.py b/nonebot/internal/matcher.py
index 11eda889..18b30adc 100644
--- a/nonebot/internal/matcher.py
+++ b/nonebot/internal/matcher.py
@@ -1,8 +1,8 @@
from types import ModuleType
from contextvars import ContextVar
from collections import defaultdict
-from contextlib import AsyncExitStack
from datetime import datetime, timedelta
+from contextlib import AsyncExitStack, contextmanager
from typing import (
TYPE_CHECKING,
Any,
@@ -661,6 +661,18 @@ class Matcher(metaclass=MatcherMeta):
if REJECT_CACHE_TARGET in self.state:
self.state[REJECT_TARGET] = self.state[REJECT_CACHE_TARGET]
+ @contextmanager
+ def ensure_context(self, bot: Bot, event: Event):
+ b_t = current_bot.set(bot)
+ e_t = current_event.set(event)
+ m_t = current_matcher.set(self)
+ try:
+ yield
+ finally:
+ current_bot.reset(b_t)
+ current_event.reset(e_t)
+ current_matcher.reset(m_t)
+
async def simple_run(
self,
bot: Bot,
@@ -673,35 +685,31 @@ class Matcher(metaclass=MatcherMeta):
f"{self} run with incoming args: "
f"bot={bot}, event={event!r}, state={state!r}"
)
- b_t = current_bot.set(bot)
- e_t = current_event.set(event)
- m_t = current_matcher.set(self)
- try:
- # Refresh preprocess state
- self.state.update(state)
- while self.handlers:
- handler = self.handlers.pop(0)
- current_handler.set(handler)
- logger.debug(f"Running handler {handler}")
- try:
- await handler(
- matcher=self,
- bot=bot,
- event=event,
- state=self.state,
- stack=stack,
- dependency_cache=dependency_cache,
- )
- except SkippedException:
- logger.debug(f"Handler {handler} skipped")
- except StopPropagation:
- self.block = True
- finally:
- logger.info(f"{self} running complete")
- current_bot.reset(b_t)
- current_event.reset(e_t)
- current_matcher.reset(m_t)
+ with self.ensure_context(bot, event):
+ try:
+ # Refresh preprocess state
+ self.state.update(state)
+
+ while self.handlers:
+ handler = self.handlers.pop(0)
+ current_handler.set(handler)
+ logger.debug(f"Running handler {handler}")
+ try:
+ await handler(
+ matcher=self,
+ bot=bot,
+ event=event,
+ state=self.state,
+ stack=stack,
+ dependency_cache=dependency_cache,
+ )
+ except SkippedException:
+ logger.debug(f"Handler {handler} skipped")
+ except StopPropagation:
+ self.block = True
+ finally:
+ logger.info(f"{self} running complete")
# 运行handlers
async def run(
diff --git a/nonebot/message.py b/nonebot/message.py
index 0a77a17c..9203d43b 100644
--- a/nonebot/message.py
+++ b/nonebot/message.py
@@ -167,17 +167,19 @@ async def _run_matcher(
)
for proc in _run_preprocessors
]:
- try:
- await asyncio.gather(*coros)
- except IgnoredException:
- logger.opt(colors=True).info(f"{matcher} running is cancelled")
- return
- except Exception as e:
- logger.opt(colors=True, exception=e).error(
- "Error when running RunPreProcessors. Running cancelled!"
- )
+ # ensure matcher function can be correctly called
+ with matcher.ensure_context(bot, event):
+ try:
+ await asyncio.gather(*coros)
+ except IgnoredException:
+ logger.opt(colors=True).info(f"{matcher} running is cancelled")
+ return
+ except Exception as e:
+ logger.opt(colors=True, exception=e).error(
+ "Error when running RunPreProcessors. Running cancelled!"
+ )
- return
+ return
exception = None
@@ -205,12 +207,14 @@ async def _run_matcher(
)
for proc in _run_postprocessors
]:
- try:
- await asyncio.gather(*coros)
- except Exception as e:
- logger.opt(colors=True, exception=e).error(
- "Error when running RunPostProcessors"
- )
+ # ensure matcher function can be correctly called
+ with matcher.ensure_context(bot, event):
+ try:
+ await asyncio.gather(*coros)
+ except Exception as e:
+ logger.opt(colors=True, exception=e).error(
+ "Error when running RunPostProcessors"
+ )
if matcher.block:
raise StopPropagation