diff --git a/docs/migration_2_to_3.rst b/docs/migration_2_to_3.rst index 0ac24c99..564ec698 100644 --- a/docs/migration_2_to_3.rst +++ b/docs/migration_2_to_3.rst @@ -94,203 +94,63 @@ Bot API However, all errors are classified by HTTP status codes, and for each method, only one type of error can be associated with a given code. Therefore, in most cases, you should check only the error type (by status code) - without inspecting the error message. + without inspecting the error message. More details can be found in the + :ref:`exceptions section » `. +Exceptions +========== -Middlewares -=========== +Mapping (v2 -> v3) +------------------- -- Middlewares can now control an execution context, e.g., using context managers. - (:ref:`Read more » `) -- All contextual data is now shared end-to-end between middlewares, filters, and handlers. - For example now you can easily pass some data into context inside middleware and - get it in the filters layer as the same way as in the handlers via keyword arguments. -- Added a mechanism named **flags** that helps customize handler behavior - in conjunction with middlewares. (:ref:`Read more » `) +- RetryAfter -> :class:`TelegramRetryAfter` (:mod:`aiogram.exceptions`) + - Important attribute in v3: ``retry_after`` (int). +- ChatMigrated / MigrateToChat -> :class:`TelegramMigrateToChat` + - Important attribute in v3: ``migrate_to_chat_id`` (int). -Keyboard Markup -=============== +- ClientDecodeError -> :class:`ClientDecodeError` + - Important attributes in v3: ``original`` (Exception) and ``data`` (response body). -- Now :class:`aiogram.types.inline_keyboard_markup.InlineKeyboardMarkup` - and :class:`aiogram.types.reply_keyboard_markup.ReplyKeyboardMarkup` no longer have methods for extension, - instead you have to use markup builders :class:`aiogram.utils.keyboard.ReplyKeyboardBuilder` - and :class:`aiogram.utils.keyboard.KeyboardBuilder` respectively - (:ref:`Read more » `) +- BadRequest -> :class:`TelegramBadRequest` +- Unauthorized -> :class:`TelegramUnauthorizedError` +- Forbidden -> :class:`TelegramForbiddenError` +- NotFound -> :class:`TelegramNotFound` +- Conflict -> :class:`TelegramConflictError` +- ServerError -> :class:`TelegramServerError` +- NetworkError -> :class:`TelegramNetworkError` +- EntityTooLarge -> :class:`TelegramEntityTooLarge` +Migration notes +--------------- -Callbacks data -============== +- Use the mapped v3 exception classes in your code; when behavior depends on + specific error details, rely on the attributes listed above (``retry_after``, + ``migrate_to_chat_id``, ``original``, ``data``) instead of parsing messages. -- The callback data factory is now strictly typed using `pydantic `_ models. - (:ref:`Read more » `) +Exceptions removed in v3 (from v2) +---------------------------------- +The list below contains common exception names that appeared in aiogram v2 but +are not defined as separate classes in the v3 codebase. For each v2 name, a +recommended v3 replacement (or handling) is provided — keep your migration +logic simple and rely on the v3 exception classes and their attributes. -Finite State machine -==================== +- MessageNotModified -> :class:`TelegramBadRequest` +- MessageToEditNotFound -> :class:`TelegramNotFound` +- MessageToDeleteNotFound -> :class:`TelegramNotFound` +- MessageCantBeDeleted -> :class:`TelegramForbiddenError` / :class:`TelegramBadRequest` +- CantParseEntities -> :class:`TelegramBadRequest` +- MessageIsTooLong -> :class:`TelegramEntityTooLarge` +- MessageIdentifierNotFound -> :class:`TelegramNotFound` +- UserDeactivated -> :class:`TelegramForbiddenError` +- CantInitiateConversation -> :class:`TelegramBadRequest` +- StickerSetNameInvalid -> :class:`TelegramBadRequest` +- ChatAdminRequired -> :class:`TelegramForbiddenError` -- State filters will no longer be automatically added to all handlers; - you will need to specify the state if you want to use it. -- Added the possibility to change the FSM strategy. For example, - if you want to control the state for each user based on chat topics rather than - the user in a chat, you can specify this in the |Dispatcher|. -- Now :class:`aiogram.fsm.state.State` and :class:`aiogram.fsm.state.StateGroup` don't have helper - methods like :code:`.set()`, :code:`.next()`, etc. - Instead, you should set states by passing them directly to - :class:`aiogram.fsm.context.FSMContext` (:ref:`Read more » `) -- The state proxy is deprecated; you should update the state data by calling - :code:`state.set_data(...)` and :code:`state.get_data()` respectively. - - -Sending Files -============= - -- From now on, you should wrap files in an InputFile object before sending them, - instead of passing the IO object directly to the API method. (:ref:`Read more » `) - - -Webhook -======= - -- The aiohttp web app configuration has been simplified. -- By default, the ability to upload files has been added when you `make requests in response to updates `_ (available for webhook only). - - -Telegram API Server -=================== - -- The :obj:`server` parameter has been moved from the |Bot| instance to :obj:`api` parameter of the :class:`~aiogram.client.session.base.BaseSession`. -- The constant :obj:`aiogram.bot.api.TELEGRAM_PRODUCTION` has been moved to :obj:`aiogram.client.telegram.PRODUCTION`. - - -Telegram objects transformation (to dict, to json, from json) -============================================================= - -- Methods :code:`TelegramObject.to_object()`, :code:`TelegramObject.to_json()` and :code:`TelegramObject.to_python()` - have been removed due to the use of `pydantic `_ models. -- :code:`TelegramObject.to_object()` should be replaced by :code:`TelegramObject.model_validate()` - (`Read more `_) -- :code:`TelegramObject.as_json()` should be replaced by :func:`aiogram.utils.serialization.deserialize_telegram_object_to_python` -- :code:`.to_python()` should be replaced by :code:`json.dumps(deserialize_telegram_object_to_python())` - -Here are some usage examples: - -- Creating an object from a dictionary representation of an object - - .. code-block:: - - # Version 2.x - message_dict = {"id": 42, ...} - message_obj = Message.to_object(message_dict) - print(message_obj) - # id=42 name='n' ... - print(type(message_obj)) - # - - .. code-block:: - - # Version 3.x - message_dict = {"id": 42, ...} - message_obj = Message.model_validate(message_dict) - print(message_obj) - # id=42 name='n' ... - print(type(message_obj)) - # - -- Creating a json representation of an object - - .. code-block:: - - # Version 2.x - async def handler(message: Message) -> None: - message_json = message.as_json() - print(message_json) - # {"id": 42, ...} - print(type(message_json)) - # - - .. code-block:: - - # Version 3.x - async def handler(message: Message) -> None: - message_json = json.dumps(deserialize_telegram_object_to_python(message)) - print(message_json) - # {"id": 42, ...} - print(type(message_json)) - # - -- Creating a dictionary representation of an object - - .. code-block:: - - async def handler(message: Message) -> None: - # Version 2.x - message_dict = message.to_python() - print(message_dict) - # {"id": 42, ...} - print(type(message_dict)) - # - - .. code-block:: - - async def handler(message: Message) -> None: - # Version 3.x - message_dict = deserialize_telegram_object_to_python(message) - print(message_dict) - # {"id": 42, ...} - print(type(message_dict)) - # - - -ChatMember tools -================ - -- Now :class:`aiogram.types.chat_member.ChatMember` no longer contains tools to resolve an object with the appropriate status. - - .. code-block:: - - # Version 2.x - from aiogram.types import ChatMember - - chat_member = ChatMember.resolve(**dict_data) - - .. code-block:: - - # Version 3.x - from aiogram.utils.chat_member import ChatMemberAdapter - - chat_member = ChatMemberAdapter.validate_python(dict_data) - - -- Now :class:`aiogram.types.chat_member.ChatMember` and all its child classes no longer - contain methods for checking for membership in certain logical groups. - As a substitute, you can use pre-defined groups or create such groups yourself - and check their entry using the :func:`isinstance` function - - .. code-block:: - - # Version 2.x - - if chat_member.is_chat_admin(): - print("ChatMember is chat admin") - - if chat_member.is_chat_member(): - print("ChatMember is in the chat") - - .. code-block:: - - # Version 3.x - - from aiogram.utils.chat_member import ADMINS, MEMBERS - - if isinstance(chat_member, ADMINS): - print("ChatMember is chat admin") - - if isinstance(chat_member, MEMBERS): - print("ChatMember is in the chat") - - .. note:: - You also can independently create group similar to ADMINS that fits the logic of your application. - - E.g., you can create a PUNISHED group and include banned and restricted members there! +Use these replacements when migrating exception handling from v2 to v3. If +you relied on catching very specific v2 exception classes, replace those +handlers with the corresponding v3 class above (or catch a broader v3 class +such as :class:`TelegramBadRequest` / :class:`TelegramAPIError`) and inspect +available attributes (see "Mapping (v2 -> v3)") for any required details.