From 99062abf683210fe9cc7aaa76287a7f8f4145725 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Tue, 21 Sep 2021 21:47:59 +0300 Subject: [PATCH] Move exceptions --- aiogram/client/session/aiohttp.py | 6 +- aiogram/client/session/base.py | 43 +++++++------ aiogram/dispatcher/dispatcher.py | 6 +- .../exceptions/special.py => exceptions.py} | 64 ++++++++++++++++++- aiogram/utils/exceptions/__init__.py | 0 aiogram/utils/exceptions/bad_request.py | 5 -- aiogram/utils/exceptions/base.py | 27 -------- aiogram/utils/exceptions/conflict.py | 5 -- aiogram/utils/exceptions/exceptions.py | 5 -- aiogram/utils/exceptions/network.py | 9 --- aiogram/utils/exceptions/not_found.py | 5 -- aiogram/utils/exceptions/server.py | 9 --- aiogram/utils/exceptions/unauthorized.py | 5 -- .../test_session/test_aiohttp_session.py | 4 +- .../test_session/test_base_session.py | 41 ++++++------ 15 files changed, 116 insertions(+), 118 deletions(-) rename aiogram/{utils/exceptions/special.py => exceptions.py} (53%) delete mode 100644 aiogram/utils/exceptions/__init__.py delete mode 100644 aiogram/utils/exceptions/bad_request.py delete mode 100644 aiogram/utils/exceptions/base.py delete mode 100644 aiogram/utils/exceptions/conflict.py delete mode 100644 aiogram/utils/exceptions/exceptions.py delete mode 100644 aiogram/utils/exceptions/network.py delete mode 100644 aiogram/utils/exceptions/not_found.py delete mode 100644 aiogram/utils/exceptions/server.py delete mode 100644 aiogram/utils/exceptions/unauthorized.py diff --git a/aiogram/client/session/aiohttp.py b/aiogram/client/session/aiohttp.py index c24d388d..ec586fea 100644 --- a/aiogram/client/session/aiohttp.py +++ b/aiogram/client/session/aiohttp.py @@ -19,8 +19,8 @@ from aiohttp import BasicAuth, ClientError, ClientSession, FormData, TCPConnecto from aiogram.methods import Request, TelegramMethod +from ...exceptions import TelegramNetworkError from ...methods.base import TelegramType -from ...utils.exceptions.network import NetworkError from .base import UNSET, BaseSession if TYPE_CHECKING: @@ -147,9 +147,9 @@ class AiohttpSession(BaseSession): ) as resp: raw_result = await resp.text() except asyncio.TimeoutError: - raise NetworkError(method=call, message="Request timeout error") + raise TelegramNetworkError(method=call, message="Request timeout error") except ClientError as e: - raise NetworkError(method=call, message=f"{type(e).__name__}: {e}") + raise TelegramNetworkError(method=call, message=f"{type(e).__name__}: {e}") response = self.check_response(method=call, status_code=resp.status, content=raw_result) return cast(TelegramType, response.result) diff --git a/aiogram/client/session/base.py b/aiogram/client/session/base.py index 07d9f1eb..3a845cfd 100644 --- a/aiogram/client/session/base.py +++ b/aiogram/client/session/base.py @@ -20,19 +20,24 @@ from typing import ( cast, ) -from aiogram.utils.exceptions.base import TelegramAPIError +from aiogram.exceptions import ( + RestartingTelegram, + TelegramAPIError, + TelegramBadRequest, + TelegramConflictError, + TelegramEntityTooLarge, + TelegramForbiddenError, + TelegramMigrateToChat, + TelegramNotFound, + TelegramRetryAfter, + TelegramServerError, + TelegramUnauthorizedError, +) from aiogram.utils.helper import Default from ...methods import Response, TelegramMethod from ...methods.base import TelegramType from ...types import UNSET, TelegramObject -from ...utils.exceptions.bad_request import BadRequest -from ...utils.exceptions.conflict import ConflictError -from ...utils.exceptions.network import EntityTooLarge -from ...utils.exceptions.not_found import NotFound -from ...utils.exceptions.server import RestartingTelegram, ServerError -from ...utils.exceptions.special import MigrateToChat, RetryAfter -from ...utils.exceptions.unauthorized import UnauthorizedError from ..telegram import PRODUCTION, TelegramAPIServer if TYPE_CHECKING: @@ -44,7 +49,7 @@ NextRequestMiddlewareType = Callable[ ["Bot", TelegramMethod[TelegramObject]], Awaitable[Response[TelegramObject]] ] RequestMiddlewareType = Callable[ - ["Bot", TelegramMethod[TelegramType], NextRequestMiddlewareType], + [NextRequestMiddlewareType, "Bot", TelegramMethod[TelegramType]], Awaitable[Response[TelegramType]], ] @@ -79,29 +84,31 @@ class BaseSession(abc.ABC): if parameters := response.parameters: if parameters.retry_after: - raise RetryAfter( + raise TelegramRetryAfter( method=method, message=description, retry_after=parameters.retry_after ) if parameters.migrate_to_chat_id: - raise MigrateToChat( + raise TelegramMigrateToChat( method=method, message=description, migrate_to_chat_id=parameters.migrate_to_chat_id, ) if status_code == HTTPStatus.BAD_REQUEST: - raise BadRequest(method=method, message=description) + raise TelegramBadRequest(method=method, message=description) if status_code == HTTPStatus.NOT_FOUND: - raise NotFound(method=method, message=description) + raise TelegramNotFound(method=method, message=description) if status_code == HTTPStatus.CONFLICT: - raise ConflictError(method=method, message=description) - if status_code in (HTTPStatus.UNAUTHORIZED, HTTPStatus.FORBIDDEN): - raise UnauthorizedError(method=method, message=description) + raise TelegramConflictError(method=method, message=description) + if status_code == HTTPStatus.UNAUTHORIZED: + raise TelegramUnauthorizedError(method=method, message=description) + if status_code == HTTPStatus.FORBIDDEN: + raise TelegramForbiddenError(method=method, message=description) if status_code == HTTPStatus.REQUEST_ENTITY_TOO_LARGE: - raise EntityTooLarge(method=method, message=description) + raise TelegramEntityTooLarge(method=method, message=description) if status_code >= HTTPStatus.INTERNAL_SERVER_ERROR: if "restart" in description: raise RestartingTelegram(method=method, message=description) - raise ServerError(method=method, message=description) + raise TelegramServerError(method=method, message=description) raise TelegramAPIError( method=method, diff --git a/aiogram/dispatcher/dispatcher.py b/aiogram/dispatcher/dispatcher.py index 9269429e..fa848547 100644 --- a/aiogram/dispatcher/dispatcher.py +++ b/aiogram/dispatcher/dispatcher.py @@ -8,13 +8,11 @@ from typing import Any, AsyncGenerator, Dict, List, Optional, Union from .. import loggers from ..client.bot import Bot +from ..exceptions import TelegramAPIError, TelegramNetworkError, TelegramServerError from ..methods import GetUpdates, TelegramMethod from ..types import Update, User from ..types.update import UpdateTypeLookupError from ..utils.backoff import Backoff, BackoffConfig -from ..utils.exceptions.base import TelegramAPIError -from ..utils.exceptions.network import NetworkError -from ..utils.exceptions.server import ServerError from .event.bases import UNHANDLED, SkipHandler from .event.telegram import TelegramEventObserver from .fsm.middleware import FSMContextMiddleware @@ -149,7 +147,7 @@ class Dispatcher(Router): while True: try: updates = await bot(get_updates, **kwargs) - except (NetworkError, ServerError) as e: + except (TelegramNetworkError, TelegramServerError) as e: # In cases when Telegram Bot API was inaccessible don't need to stop polling process # because some of developers can't make auto-restarting of the script loggers.dispatcher.error("Failed to fetch updates - %s: %s", type(e).__name__, e) diff --git a/aiogram/utils/exceptions/special.py b/aiogram/exceptions.py similarity index 53% rename from aiogram/utils/exceptions/special.py rename to aiogram/exceptions.py index d2044ec2..6f60fa64 100644 --- a/aiogram/utils/exceptions/special.py +++ b/aiogram/exceptions.py @@ -1,9 +1,35 @@ +from typing import Optional + from aiogram.methods import TelegramMethod from aiogram.methods.base import TelegramType -from aiogram.utils.exceptions.base import TelegramAPIError -class RetryAfter(TelegramAPIError): +class TelegramAPIError(Exception): + url: Optional[str] = None + + def __init__( + self, + method: TelegramMethod[TelegramType], + message: str, + ) -> None: + self.method = method + self.message = message + + def render_description(self) -> str: + return self.message + + def __str__(self) -> str: + message = [self.render_description()] + if self.url: + message.append(f"(background on this error at: {self.url})") + return "\n".join(message) + + +class TelegramNetworkError(TelegramAPIError): + pass + + +class TelegramRetryAfter(TelegramAPIError): url = "https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this" def __init__( @@ -23,7 +49,7 @@ class RetryAfter(TelegramAPIError): return description -class MigrateToChat(TelegramAPIError): +class TelegramMigrateToChat(TelegramAPIError): url = "https://core.telegram.org/bots/api#responseparameters" def __init__( @@ -42,3 +68,35 @@ class MigrateToChat(TelegramAPIError): if chat_id := getattr(self.method, "chat_id", None): description += f" from {chat_id}" return description + + +class TelegramBadRequest(TelegramAPIError): + pass + + +class TelegramNotFound(TelegramAPIError): + pass + + +class TelegramConflictError(TelegramAPIError): + pass + + +class TelegramUnauthorizedError(TelegramAPIError): + pass + + +class TelegramForbiddenError(TelegramAPIError): + pass + + +class TelegramServerError(TelegramAPIError): + pass + + +class RestartingTelegram(TelegramServerError): + pass + + +class TelegramEntityTooLarge(TelegramNetworkError): + url = "https://core.telegram.org/bots/api#sending-files" diff --git a/aiogram/utils/exceptions/__init__.py b/aiogram/utils/exceptions/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/aiogram/utils/exceptions/bad_request.py b/aiogram/utils/exceptions/bad_request.py deleted file mode 100644 index de1a0e2d..00000000 --- a/aiogram/utils/exceptions/bad_request.py +++ /dev/null @@ -1,5 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class BadRequest(TelegramAPIError): - pass diff --git a/aiogram/utils/exceptions/base.py b/aiogram/utils/exceptions/base.py deleted file mode 100644 index fefd3db8..00000000 --- a/aiogram/utils/exceptions/base.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Optional, TypeVar - -from aiogram.methods import TelegramMethod -from aiogram.methods.base import TelegramType - -ErrorType = TypeVar("ErrorType") - - -class TelegramAPIError(Exception): - url: Optional[str] = None - - def __init__( - self, - method: TelegramMethod[TelegramType], - message: str, - ) -> None: - self.method = method - self.message = message - - def render_description(self) -> str: - return self.message - - def __str__(self) -> str: - message = [self.render_description()] - if self.url: - message.append(f"(background on this error at: {self.url})") - return "\n".join(message) diff --git a/aiogram/utils/exceptions/conflict.py b/aiogram/utils/exceptions/conflict.py deleted file mode 100644 index 965b328c..00000000 --- a/aiogram/utils/exceptions/conflict.py +++ /dev/null @@ -1,5 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class ConflictError(TelegramAPIError): - pass diff --git a/aiogram/utils/exceptions/exceptions.py b/aiogram/utils/exceptions/exceptions.py deleted file mode 100644 index de1a0e2d..00000000 --- a/aiogram/utils/exceptions/exceptions.py +++ /dev/null @@ -1,5 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class BadRequest(TelegramAPIError): - pass diff --git a/aiogram/utils/exceptions/network.py b/aiogram/utils/exceptions/network.py deleted file mode 100644 index b802ce69..00000000 --- a/aiogram/utils/exceptions/network.py +++ /dev/null @@ -1,9 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class NetworkError(TelegramAPIError): - pass - - -class EntityTooLarge(NetworkError): - url = "https://core.telegram.org/bots/api#sending-files" diff --git a/aiogram/utils/exceptions/not_found.py b/aiogram/utils/exceptions/not_found.py deleted file mode 100644 index 6fa87a06..00000000 --- a/aiogram/utils/exceptions/not_found.py +++ /dev/null @@ -1,5 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class NotFound(TelegramAPIError): - pass diff --git a/aiogram/utils/exceptions/server.py b/aiogram/utils/exceptions/server.py deleted file mode 100644 index c45c9f01..00000000 --- a/aiogram/utils/exceptions/server.py +++ /dev/null @@ -1,9 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class ServerError(TelegramAPIError): - pass - - -class RestartingTelegram(ServerError): - pass diff --git a/aiogram/utils/exceptions/unauthorized.py b/aiogram/utils/exceptions/unauthorized.py deleted file mode 100644 index 789574a5..00000000 --- a/aiogram/utils/exceptions/unauthorized.py +++ /dev/null @@ -1,5 +0,0 @@ -from aiogram.utils.exceptions.base import TelegramAPIError - - -class UnauthorizedError(TelegramAPIError): - pass diff --git a/tests/test_api/test_client/test_session/test_aiohttp_session.py b/tests/test_api/test_client/test_session/test_aiohttp_session.py index 36c9e17a..291991be 100644 --- a/tests/test_api/test_client/test_session/test_aiohttp_session.py +++ b/tests/test_api/test_client/test_session/test_aiohttp_session.py @@ -9,9 +9,9 @@ from aresponses import ResponsesMockServer from aiogram import Bot from aiogram.client.session import aiohttp from aiogram.client.session.aiohttp import AiohttpSession +from aiogram.exceptions import TelegramNetworkError from aiogram.methods import Request, TelegramMethod from aiogram.types import UNSET, InputFile -from aiogram.utils.exceptions.network import NetworkError from tests.mocked_bot import MockedBot try: @@ -187,7 +187,7 @@ class TestAiohttpSession: new_callable=CoroutineMock, side_effect=side_effect, ): - with pytest.raises(NetworkError): + with pytest.raises(TelegramNetworkError): await bot.get_me() async def test_stream_content(self, aresponses: ResponsesMockServer): diff --git a/tests/test_api/test_client/test_session/test_base_session.py b/tests/test_api/test_client/test_session/test_base_session.py index d4e28293..217b593f 100644 --- a/tests/test_api/test_client/test_session/test_base_session.py +++ b/tests/test_api/test_client/test_session/test_base_session.py @@ -7,16 +7,21 @@ import pytest from aiogram import Bot from aiogram.client.session.base import BaseSession, TelegramType from aiogram.client.telegram import PRODUCTION, TelegramAPIServer +from aiogram.exceptions import ( + RestartingTelegram, + TelegramAPIError, + TelegramBadRequest, + TelegramConflictError, + TelegramEntityTooLarge, + TelegramForbiddenError, + TelegramMigrateToChat, + TelegramNotFound, + TelegramRetryAfter, + TelegramServerError, + TelegramUnauthorizedError, +) from aiogram.methods import DeleteMessage, GetMe, TelegramMethod from aiogram.types import UNSET, User -from aiogram.utils.exceptions.bad_request import BadRequest -from aiogram.utils.exceptions.base import TelegramAPIError -from aiogram.utils.exceptions.conflict import ConflictError -from aiogram.utils.exceptions.network import EntityTooLarge -from aiogram.utils.exceptions.not_found import NotFound -from aiogram.utils.exceptions.server import RestartingTelegram, ServerError -from aiogram.utils.exceptions.special import MigrateToChat, RetryAfter -from aiogram.utils.exceptions.unauthorized import UnauthorizedError from tests.mocked_bot import MockedBot try: @@ -153,25 +158,25 @@ class TestBaseSession: "status_code,content,error", [ [200, '{"ok":true,"result":true}', None], - [400, '{"ok":false,"description":"test"}', BadRequest], + [400, '{"ok":false,"description":"test"}', TelegramBadRequest], [ 400, '{"ok":false,"description":"test", "parameters": {"retry_after": 1}}', - RetryAfter, + TelegramRetryAfter, ], [ 400, '{"ok":false,"description":"test", "parameters": {"migrate_to_chat_id": -42}}', - MigrateToChat, + TelegramMigrateToChat, ], - [404, '{"ok":false,"description":"test"}', NotFound], - [401, '{"ok":false,"description":"test"}', UnauthorizedError], - [403, '{"ok":false,"description":"test"}', UnauthorizedError], - [409, '{"ok":false,"description":"test"}', ConflictError], - [413, '{"ok":false,"description":"test"}', EntityTooLarge], + [404, '{"ok":false,"description":"test"}', TelegramNotFound], + [401, '{"ok":false,"description":"test"}', TelegramUnauthorizedError], + [403, '{"ok":false,"description":"test"}', TelegramForbiddenError], + [409, '{"ok":false,"description":"test"}', TelegramConflictError], + [413, '{"ok":false,"description":"test"}', TelegramEntityTooLarge], [500, '{"ok":false,"description":"restarting"}', RestartingTelegram], - [500, '{"ok":false,"description":"test"}', ServerError], - [502, '{"ok":false,"description":"test"}', ServerError], + [500, '{"ok":false,"description":"test"}', TelegramServerError], + [502, '{"ok":false,"description":"test"}', TelegramServerError], [499, '{"ok":false,"description":"test"}', TelegramAPIError], [499, '{"ok":false,"description":"test"}', TelegramAPIError], ],