Перейти к содержанию

Обработка ошибок

Иногда при запросах к api вконтакте возникают ошибки, для их обработки во фреймворке предусмотрено несколько инструментов

try ... except VKAPIError()

Для начала разъясним что такое VKAPIError, это объект CodeErrorFactory, особенность которого заключается в том, чтобы ошибка идентифицировалась в except и без указанного кода (try except VKAPIError()) и при указании кода (try except VKAPIError(code))

В VKAPIError есть три поля:

  • code - код ошибки, int
  • error_description - описание ошибки, str
  • raw_error - то что вернуло vk в качестве ошибки (нужно например для обработки капчи), dict

Чтобы использовать 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_description)

error handler

Инструмент будет рассматриваться конкретно с ботом, хоть это и отдельный объект, так как это - туториал - упрощенный вариант документации

Техническая документация по хендлеру ошибок здесь

У хендлера ошибок есть три основных метода:

  • register_error_handler, который принимает саму ошибку и асинхронную функцию хендлер. Теперь если возникнет указанная ошибка, исполнится указанный хендлер
  • register_undefined_error_handler, который принимает асинхронную функцию хендлер. Теперь если возникнет неизвестная ошибка исполнится этот хендлер
  • wraps_error_handler - используется мануально как декоратор, теперь декорированная функция будет обернута этим хендлером ошибок (не нужно декорировать все функции подряд, все функции которые исполняются внутри встроенного поллинга оборачиваются хендлером ошибок по умолчанию)
from vkbottle import Bot, VKAPIError

bot = Bot("token")

async def runtime_error_handler(e: RuntimeError):
    print("возникла ошибка runtime", e)

async def unable_to_write_handler(e: VKAPIError):
    print("человек не разрешил отправлять сообщения", e)

bot.error_handler.register_error_handler(RuntimeError, runtime_error_handler)
bot.error_handler.register_error_handler(VKAPIError(902), unable_to_write_handler)

# ...

В примере создано для хендлера ошибок: для RuntimeError и конкретизированного VKAPIError

Еще у хендлера ошибок есть атрибут redirect_argument, который в данном случае позволяет передать в асинхронную функцию хендлер не только саму ошибку но и контекстные аргументы из правил и мидлварей которые вернулись в исполняемый фреймворком хендлер (который и вызвал ошибку)

Он принимает boolean значение

swear

Инструмент будет рассматриваться конкретно с ботом, хоть это и отдельный объект, так как это - туториал - упрощенный вариант документации

Краткий вариант хендлера ошибок одним декоратором, важно что swear может декорировать как синхронные, так и асинхронные функции

from vkbottle import swear

В swear необходимо первым аргументом передать ошибку, которую он будет хендлить, например тот же RuntimeError и на выбор:

  • exception_handler=func - если у вас есть хендлер которым вы будете хендлить ошибку и возвращать из него нужное значение для функции
  • just_return=True - если вам нужно просто вернуть ошибку из функции
  • just_log=True - если вам нужно логировать ошибку и вернуть из декорированной функции None
from vkbottle import swear

@swear(RuntimeError, just_return=True)
def my_func():
    raise RuntimeError("error")

my_func() # RuntimeError("error")