diff --git a/CHANGES/1147.feature b/CHANGES/1147.feature new file mode 100644 index 00000000..fa34e703 --- /dev/null +++ b/CHANGES/1147.feature @@ -0,0 +1 @@ +If router does not support custom event it does not break and passes it to included routers \ No newline at end of file diff --git a/aiogram/dispatcher/event/telegram.py b/aiogram/dispatcher/event/telegram.py index bb943004..a468816c 100644 --- a/aiogram/dispatcher/event/telegram.py +++ b/aiogram/dispatcher/event/telegram.py @@ -49,8 +49,9 @@ class TelegramEventObserver: def _resolve_middlewares(self) -> List[MiddlewareType[TelegramObject]]: middlewares: List[MiddlewareType[TelegramObject]] = [] for router in reversed(tuple(self.router.chain_head)): - observer = router.observers[self.event_name] - middlewares.extend(observer.middleware) + observer = router.observers.get(self.event_name) + if observer: + middlewares.extend(observer.middleware) return middlewares diff --git a/aiogram/dispatcher/router.py b/aiogram/dispatcher/router.py index 86359ce0..85c41ae8 100644 --- a/aiogram/dispatcher/router.py +++ b/aiogram/dispatcher/router.py @@ -105,27 +105,31 @@ class Router: async def propagate_event(self, update_type: str, event: TelegramObject, **kwargs: Any) -> Any: kwargs.update(event_router=self) - observer = self.observers[update_type] + observer = self.observers.get(update_type) async def _wrapped(telegram_event: TelegramObject, **data: Any) -> Any: return await self._propagate_event( observer=observer, update_type=update_type, event=telegram_event, **data ) - return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs) + if observer: + return await observer.wrap_outer_middleware(_wrapped, event=event, data=kwargs) + return await _wrapped(event, **kwargs) async def _propagate_event( self, - observer: TelegramEventObserver, + observer: Optional[TelegramEventObserver], update_type: str, event: TelegramObject, **kwargs: Any, ) -> Any: - response = await observer.trigger(event, **kwargs) - if response is REJECTED: - return UNHANDLED - if response is not UNHANDLED: - return response + response = UNHANDLED + if observer: + response = await observer.trigger(event, **kwargs) + if response is REJECTED: + return UNHANDLED + if response is not UNHANDLED: + return response for router in self.sub_routers: response = await router.propagate_event(update_type=update_type, event=event, **kwargs) diff --git a/tests/test_dispatcher/test_router.py b/tests/test_dispatcher/test_router.py index 3404822d..1ac78480 100644 --- a/tests/test_dispatcher/test_router.py +++ b/tests/test_dispatcher/test_router.py @@ -1,6 +1,7 @@ import pytest from aiogram.dispatcher.event.bases import UNHANDLED, SkipHandler, skip +from aiogram.dispatcher.event.telegram import TelegramEventObserver from aiogram.dispatcher.router import Router @@ -161,3 +162,20 @@ class TestRouter: assert tuple(r2_1.chain_head) == (r2_1, r1) assert tuple(r2_2.chain_head) == (r2_2, r1) assert tuple(r3.chain_head) == (r3, r2_1, r1) + + async def test_custom_evenv_nested_router(self): + r1 = Router() + r2 = Router() + r3 = Router() + r3.observers["custom-event"] = TelegramEventObserver(r3, event_name="custom-event") + + async def handler(evt): + return evt + + r1.include_router(r2) + r1.include_router(r3) + r3.observers["custom-event"].register(handler) + + assert await r1.propagate_event(update_type="custom-event", event=None) is None + assert await r2.propagate_event(update_type="custom-event", event=None) is UNHANDLED + assert await r3.propagate_event(update_type="custom-event", event=None) is None