Move exceptions

This commit is contained in:
Alex Root Junior 2021-09-21 21:47:59 +03:00
parent 26d531a304
commit 99062abf68
15 changed files with 116 additions and 118 deletions

View file

@ -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)

View file

@ -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,

View file

@ -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)

View file

@ -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"

View file

@ -1,5 +0,0 @@
from aiogram.utils.exceptions.base import TelegramAPIError
class BadRequest(TelegramAPIError):
pass

View file

@ -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)

View file

@ -1,5 +0,0 @@
from aiogram.utils.exceptions.base import TelegramAPIError
class ConflictError(TelegramAPIError):
pass

View file

@ -1,5 +0,0 @@
from aiogram.utils.exceptions.base import TelegramAPIError
class BadRequest(TelegramAPIError):
pass

View file

@ -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"

View file

@ -1,5 +0,0 @@
from aiogram.utils.exceptions.base import TelegramAPIError
class NotFound(TelegramAPIError):
pass

View file

@ -1,9 +0,0 @@
from aiogram.utils.exceptions.base import TelegramAPIError
class ServerError(TelegramAPIError):
pass
class RestartingTelegram(ServerError):
pass

View file

@ -1,5 +0,0 @@
from aiogram.utils.exceptions.base import TelegramAPIError
class UnauthorizedError(TelegramAPIError):
pass

View file

@ -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):

View file

@ -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],
],