@DeusExe

С чем может быть связана ошибка «asyncio.exceptions.CancelledError»?

Всем привет. Ранее не сталкивался с такой ошибкой. Завершаю бота кнопкой stop, а не ctrl+c как пишет консоль. Бесконечных циклов нет. Может что-то не так с main:

async def main():
    try:
        await client.start()
        await client.connect()
        await dp.start_polling(bot)
    finally:
        await bot.session.close()

if __name__ == "__main__":
    asyncio.run(main())


Ошибка:

Traceback (most recent call last):
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\PycharmProjects\MY-TELEGRAM-BOT\BOT\MAIN.py", line 436, in main
    await dp.start_polling(bot)
  File "C:\Users\ALEXE\PycharmProjects\MY-TELEGRAM-BOT\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 543, in start_polling
    done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 418, in wait
    return await _wait(fs, timeout, return_when, loop)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 525, in _wait
    await waiter
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\ALEXE\PycharmProjects\MY-TELEGRAM-BOT\BOT\MAIN.py", line 441, in <module>
    asyncio.run(main())
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 123, in run
    raise KeyboardInterrupt()
KeyboardInterrupt


Буду благодарен за любые идеи.
  • Вопрос задан
  • 490 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Открой доки и почитай. CancelledError выбрасывается в корутине, когда она завёрнута в таск через create_task() и на этом таске вызван метод cancel(). Это позволяет прервать выполнение корутины через выбрасывание специального исключения. Исключение не наследуется от Exception, поэтому обычный try-except его не ловит, если только специально не указать try ... except CancelledError. Так сделано, потому что при выходе через всплывание исключения будут отрабатывать все нормальные питоновские механизмы: блоки finally, блоки with и так далее.
Я полагаю, команда на остановку бота делает cancel() на его главной корутине, скорее всего запущенной внутри start_polling(). Это исключение всплывает в твой main(). Но поскольку main() выполняется в asyncio.run(), то исключение всплывает туда. Это исключение не имеет особого смысла вне asyncio, так что я полагаю, run() ловит это исключение и вместо него выбрасывает KeyboardInterrupt() как ближайший не-асинхронный эквивалент. Это исключение всплывает на верхний уровень и останавливает интерпретатор.

Ты можешь ловить CancelledError в main(), чтобы спокойно завершить работу бота. Ну или ловить KeyboardInterrupt() в теле скрипта, на вызове asyncio.run().
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
QWERTYUIOPas
@QWERTYUIOPas
КраткоОСеБе
Не нужны скобки после main, а то Вы не функцию, а None передаёте:

asyncio.run(main())

А надо так:

asyncio.run(main)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы