Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Обробка помилок в асинхронному коді | Асинхронне програмування
Структурне програмування на Python

Обробка помилок в асинхронному коді

Свайпніть щоб показати меню

Під час роботи з асинхронним кодом у Python із використанням asyncio обробка помилок потребує особливої уваги, оскільки виключення можуть поширюватися інакше, ніж у синхронному коді. У синхронному контексті зазвичай використовується блок try-except для перехоплення виключень навколо коду, який може завершитися помилкою. Така ж структура працює і всередині корутин, але при роботі з задачами, які плануються через asyncio, виникають додаткові нюанси.

Якщо у середині корутини, визначеної через async def, виникає виключення і його не перехоплено, воно буде передано до того місця, де корутину очікують через await. Якщо ви використовуєте await для корутини, яка викликає виключення, це виключення буде піднято у місці виклику await, і його можна перехопити блоком try-except. Однак якщо ви плануєте корутину як задачу за допомогою asyncio.create_task() або asyncio.ensure_future(), виключення не передається одразу. Воно зберігається у об'єкті задачі і буде піднято лише тоді, коли ви явно очікуєте цю задачу або перевіряєте її результат.

Це означає, що якщо ви не обробите виключення всередині корутини або під час очікування задачі, ви можете пропустити критичні помилки, або ж виключення буде зафіксовано циклом подій як "необроблене виключення". Щоб цього уникнути, слід обробляти виключення або всередині корутини за допомогою try-except, або переконатися, що всі задачі очікуються і їх результати обробляються належним чином. Такий підхід допомагає зберігати стабільність асинхронних програм і спрощує налагодження.

Нижче наведено приклад коду на Python, який демонструє, як обробляти виключення всередині асинхронної корутини за допомогою блоку try-except:

import asyncio

async def may_fail(n):
    try:
        if n % 2 == 0:
            raise ValueError(f"Even number error: {n}")
        print(f"Processed: {n}")
    except ValueError as e:
        print(f"Caught exception in coroutine: {e}")

async def main():
    tasks = [asyncio.create_task(may_fail(i)) for i in range(3)]
    await asyncio.gather(*tasks)

asyncio.run(main())

Очікуваний результат:

Caught exception in coroutine: Even number error: 0
Processed: 1
Caught exception in coroutine: Even number error: 2

У цьому прикладі визначено асинхронну корутину may_fail, яка використовує блок try-except для перехоплення виключень типу ValueError при обробці парних чисел. Якщо n парне, виникає ValueError, який перехоплюється всередині корутини, і виводиться відповідне повідомлення. Корутину main використано для планування трьох задач через asyncio.create_task() та їх збору за допомогою asyncio.gather(), що гарантує очікування всіх задач. Такий підхід забезпечує коректну обробку виключень у корутинах і запобігає появі необроблених виключень у циклі подій.

question mark

Як правильно обробляти виключення в асинхронних корутинах, щоб уникнути необроблених помилок?

Виберіть усі правильні відповіді

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 4. Розділ 5

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Секція 4. Розділ 5
some-alt