Last active
December 13, 2020 12:47
-
-
Save antibagr/329f4bf0d91e890b07ddbc81402a7d66 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
from typing import Callable, Awaitable, Any, Union | |
from aiogram import types | |
# sends to user when handler raises exception | |
ERROR_MESSAGE = "No, I'm dying. Please tell BotFather I love him ..." | |
def wrap_exception(f: Awaitable) -> Awaitable: | |
""" | |
Decorates f with handling exception. | |
If any handler raises an exception, a user will receive ERROR_MESSAGE | |
And then exception will be raised again to go up to errors_handler | |
""" | |
@wraps(f) | |
async def decorator(trg: Union[types.Message, types.CallbackQuery], *args, **kwargs) -> Any: | |
try: | |
return await f(trg, *args, **kwargs) | |
except Exception: | |
user = trg if isinstance(trg, types.Message) else trg.message | |
await user.answer(ERROR_MESSAGE) | |
# Exception will be raised after a user has received | |
# information about something bad happened | |
# on a server side. | |
raise | |
return decorator | |
def get_updated_handler(original_handler: Callable): | |
""" | |
What do we do here is wrapping every handler in a whole bot application | |
with a wrap_exception decorator which simply tries to execute function | |
And if something bad happend it will nofity whoever called the function | |
That something bad happended and after it exception will be raised up | |
to the Dispatcher error handler. | |
:param Callable original_handler: . | |
""" | |
def updated_handler(*handler_args, **handler_kwargs) -> Callable: | |
""" | |
A function will be called instead of dp.message_handler | |
And will return updated_decorator instead of inner aiogram | |
Decorator | |
""" | |
def updated_decorator(f: Awaitable) -> Awaitable: | |
""" | |
Actially this function is returned when some handler | |
called @dp.message_handler(). | |
A function still may think that it's the same as before | |
But what actually happens is that we wrap it with our wrap_exception | |
decorator. | |
So when it will be called and if it will raise exception | |
We can be sure about a user received an information about this exception | |
Instead of waiting forever without knowning nobody gonna answer him. | |
""" | |
handler_decorator = original_handler(*handler_args, **handler_kwargs) | |
safe_call = handler_decorator(wrap_exception(f)) | |
return safe_call | |
return updated_decorator | |
return updated_handler | |
""" | |
How to use it anyway ? | |
import aiogram | |
bot = aiogram.Bot(token=BOT_TOKEN) | |
dp = aiogram.Dispatcher(bot) | |
dp.message_handler = get_updated_handler(dp.message_handler) | |
dp.callback_query_handler = get_updated_handler(dp.callback_query_handler) | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment