From ca4d7397f8d77c243fa609c1f69170614b45b9be Mon Sep 17 00:00:00 2001 From: yanyongyu Date: Mon, 6 Dec 2021 00:17:52 +0800 Subject: [PATCH] :bug: add skip handle for process --- nonebot/dependencies/__init__.py | 2 +- nonebot/exception.py | 12 +++++ nonebot/matcher.py | 7 ++- nonebot/message.py | 87 +++++++++++++++++++++----------- 4 files changed, 76 insertions(+), 32 deletions(-) diff --git a/nonebot/dependencies/__init__.py b/nonebot/dependencies/__init__.py index d15a2ddc..04d91d15 100644 --- a/nonebot/dependencies/__init__.py +++ b/nonebot/dependencies/__init__.py @@ -156,7 +156,7 @@ async def solve_dependencies( f"type {type(value)} not match depends {_dependent.func} " f"annotation {field._type_display()}, ignored" ) - raise SkippedException + raise SkippedException(field, value) else: values[field.name] = value diff --git a/nonebot/exception.py b/nonebot/exception.py index 193023b7..f1e95fd6 100644 --- a/nonebot/exception.py +++ b/nonebot/exception.py @@ -8,6 +8,8 @@ from typing import Any, Optional +from pydantic.fields import ModelField + class NoneBotException(Exception): """ @@ -124,6 +126,16 @@ class SkippedException(MatcherException): 可以在 ``Handler`` 中通过 ``Matcher.skip()`` 抛出。 """ + def __init__(self, param: ModelField, value: Any): + self.param = param + self.value = value + + def __repr__(self): + return f"" + + def __str__(self): + self.__repr__() + class PausedException(MatcherException): """ diff --git a/nonebot/matcher.py b/nonebot/matcher.py index 1bad8a6e..19c7e553 100644 --- a/nonebot/matcher.py +++ b/nonebot/matcher.py @@ -669,8 +669,11 @@ class Matcher(metaclass=MatcherMeta): _stack=stack, _dependency_cache=dependency_cache, ) - except SkippedException: - pass + except SkippedException as e: + logger.debug( + f"Handler {handler} param {e.param.name} value {e.value} " + f"mismatch type {e.param._type_display()}, skipped" + ) except RejectedException: self.handlers.insert(0, handler) # type: ignore diff --git a/nonebot/message.py b/nonebot/message.py index 3f89b971..b36b3049 100644 --- a/nonebot/message.py +++ b/nonebot/message.py @@ -8,7 +8,16 @@ NoneBot 内部处理并按优先级分发事件给所有事件响应器,提供 import asyncio from datetime import datetime from contextlib import AsyncExitStack -from typing import TYPE_CHECKING, Any, Set, Dict, Type, Optional +from typing import ( + TYPE_CHECKING, + Any, + Set, + Dict, + List, + Type, + Optional, + Coroutine, +) from nonebot import params from nonebot.log import logger @@ -16,7 +25,12 @@ from nonebot.rule import TrieRule from nonebot.handler import Handler from nonebot.utils import escape_tag from nonebot.matcher import Matcher, matchers -from nonebot.exception import NoLogException, StopPropagation, IgnoredException +from nonebot.exception import ( + NoLogException, + StopPropagation, + IgnoredException, + SkippedException, +) from nonebot.typing import ( T_State, T_DependencyCache, @@ -100,6 +114,13 @@ def run_postprocessor(func: T_RunPostProcessor) -> T_RunPostProcessor: # FIXME: run handler with try/except skipped exception +async def _run_coro_with_catch(coro: Coroutine[Any, Any, Any]) -> Any: + try: + return await coro + except SkippedException: + pass + + async def _check_matcher( priority: int, Matcher: Type[Matcher], @@ -150,13 +171,15 @@ async def _run_matcher( coros = list( map( - lambda x: x( - matcher=matcher, - bot=bot, - event=event, - state=state, - _stack=stack, - _dependency_cache=dependency_cache, + lambda x: _run_coro_with_catch( + x( + matcher=matcher, + bot=bot, + event=event, + state=state, + _stack=stack, + _dependency_cache=dependency_cache, + ) ), _run_preprocessors, ) @@ -189,14 +212,16 @@ async def _run_matcher( coros = list( map( - lambda x: x( - matcher=matcher, - exception=exception, - bot=bot, - event=event, - state=state, - _stack=stack, - _dependency_cache=dependency_cache, + lambda x: _run_coro_with_catch( + x( + matcher=matcher, + exception=exception, + bot=bot, + event=event, + state=state, + _stack=stack, + _dependency_cache=dependency_cache, + ) ), _run_postprocessors, ) @@ -247,12 +272,14 @@ async def handle_event(bot: "Bot", event: "Event") -> None: async with AsyncExitStack() as stack: coros = list( map( - lambda x: x( - bot=bot, - event=event, - state=state, - _stack=stack, - _dependency_cache=dependency_cache, + lambda x: _run_coro_with_catch( + x( + bot=bot, + event=event, + state=state, + _stack=stack, + _dependency_cache=dependency_cache, + ) ), _event_preprocessors, ) @@ -307,12 +334,14 @@ async def handle_event(bot: "Bot", event: "Event") -> None: coros = list( map( - lambda x: x( - bot=bot, - event=event, - state=state, - _stack=stack, - _dependency_cache=dependency_cache, + lambda x: _run_coro_with_catch( + x( + bot=bot, + event=event, + state=state, + _stack=stack, + _dependency_cache=dependency_cache, + ) ), _event_postprocessors, )