Обработка ошибок
Иногда при запросах к api вконтакте возникают ошибки, для их обработки во фреймворке предусмотрено несколько инструментов
try ... except VKAPIError
Для начала разъясним что такое VKAPIError
, это подтип CodeException
, особенность которого заключается в том, чтобы ошибка идентифицировалась в except и без указанного кода (try except VKAPIError
) и при указании кода (try except VKAPIError[code]
)
В VKAPIError
есть два поля:
code
- код ошибки, interror_msg
- описание ошибки, str
Чтобы использовать VKAPIError
нужно импортировать его:
from vkbottle import VKAPIError
Теперь можно обернуть какой нибудь код с запросом к API:
try:
await api.wall.post()
except VKAPIError as e:
print("Возникла ошибка", e.code)
При исполнении этого кода vk вернет ошибку, из-за того что не были переданы нужные параметры
try ... except VKAPIError[code]
Кроме более общего способа для обработки всех ошибок vk в одном блоке except, вы можете воспользоваться более конкретным VKAPIError[code]
Примечание
Список всех ошибок с их кодами вы можете найти здесь
Сделаем несколько блоков для демонстрации того, как первый и второй способ можно комбинировать
try:
await api.messages.send(peer_id=1, message="привет!", random_id=0)
except VKAPIError[902] as e:
print("не могу отправить сообщение из-за настроек приватности")
except VKAPIError as e:
print("не могу отправить:", e.error_msg)
Специфичные ошибки
Некоторые ошибки vk имеют дополнительные поля, которые могут понадобиться вам для их обработки:
CaptchaError
:captcha_sid
- идентификатор captcha, intcaptcha_img
- ссылка на изображение, str
ErrorHandler
Примечание
Инструмент будет рассматриваться конкретно с ботом, хоть это и отдельный объект, так как это - туториал - упрощенный вариант документации
Техническая документация по хендлеру ошибок здесь
У ErrorHandler
есть 4 метода:
register_error_handler
- декоратор, принимающий типы ошибок и асинхронную функцию-хендлер. Если возникнет одна из указанных ошибок (или её подтипа), исполнится указанный хендлер.register_undefined_error_handler
- декоратор, принимающий тип ошибки и асинхронную функцию-хендлер. Если возникнет неизвестная ошибка, исполнится этот хендлер.handle
, принимающий экземпляр ошибки. Передаёт ошибку в соответствующий хендлер, зарегистрированный с помощью вышеописанных декораторов. Если для данной ошибки нет хендлера, поднимает её.catch
- декоратор. Ловит ошибки из декорированной функции и передаёт их методуhandle
.
from vkbottle import Bot, VKAPIError
bot = Bot("token")
@bot.error_handler.register_error_handler(RuntimeError)
async def runtime_error_handler(e: RuntimeError):
print("возникла ошибка runtime", e)
@bot.error_handler.register_error_handler(VKAPIError[902])
async def unable_to_write_handler(e: VKAPIError):
print("человек не разрешил отправлять сообщения", e)
В примере создано 2 хендлера ошибок: для RuntimeError
и конкретизированного VKAPIError
Также можно регистрировать хендлеры сразу для нескольких типов ошибок:
from typing import Union
from vkbottle import Bot, VKAPIError
bot = Bot("token")
@bot.error_handler.register_error_handler(TypeError, ValueError)
async def type_or_value_error_handler(e: Union[TypeError, ValueError]):
print("возникла ошибка type или value", e)
@bot.error_handler.register_error_handler(*VKAPIError[6, 9])
async def limit_reached_write_handler(e: VKAPIError):
print("ой, слишком много запросов", e)
Ещё у ErrorHandler
есть параметр redirect_arguments: bool
, который позволяет передавать в хендлер аргументы из задекорированной с помощью catch
функции. В связке с ботом позволяет передать в хендлер контекстные аргументы из правил и мидлварей.
Подробнее про ErrorHandler.catch
можно почитать здесь