Обробка помилок в асинхронному коді
Свайпніть щоб показати меню
Під час роботи з асинхронним кодом у 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(), що гарантує очікування всіх задач. Такий підхід забезпечує коректну обробку виключень у корутинах і запобігає появі необроблених виключень у циклі подій.
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат