Назад к вопросам
Middle
77
questionbank
Как можно отловить исключения при работе с асинхронным кодом?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Используя try...except блоки.
import asyncio
async def my_async_function():
# Какой-то асинхронный код, который может вызвать исключение
await asyncio.sleep(1)
raise ValueError("Что-то пошло не так!")
async def main():
try:
await my_async_function()
except ValueError as e:
print(f"Поймано исключение: {e}")
except Exception as e:
print(f"Поймано непредвиденное исключение: {e}")
if __name__ == "__main__":
asyncio.run(main())
В случае конкурентного запуска нескольких асинхронных задач с использованием asyncio.gather, исключения могут обрабатываться следующим образом:
import asyncio
async def task_with_exception():
await asyncio.sleep(0.5)
raise RuntimeError("Ошибка в одной из задач")
async def task_without_exception():
await asyncio.sleep(1)
print("Задача без исключения завершена")
async def concurrent_execution():
try:
# return_exceptions=True позволяет собрать все исключения вместо падения при первом же
results = await asyncio.gather(
task_with_exception(),
task_without_exception(),
return_exceptions=True
)
for result in results:
if isinstance(result, Exception):
print(f"Обнаружено исключение в задаче: {result}")
else:
print(f"Задача успешно завершена с результатом: {result}")
except Exception as e:
# Этот блок выполнится, только если return_exceptions=False и
# одна из задач выбросила исключение до того, как мы его поймали внутри gather
print(f"Обнаружено исключение при выполнении gather: {e}")
if __name__ == "__main__":
asyncio.run(concurrent_execution())
Параметр return_exceptions=True в asyncio.gather позволяет собрать исключения как результаты выполнения, вместо того, чтобы остановить выполнение всех задач при возникновении первого исключения.
При использовании asyncio.create_task или подобных низкоуровневых механизмов, исключения могут быть получены с помощью метода .exception() у объекта задачи после её завершения, если они не были обработаны внутри самой корутины:
import asyncio
async def failing_task():
await asyncio.sleep(0.1)
raise TypeError("Неправильный тип!")
async def monitor_task():
task = asyncio.create_task(failing_task())
await task # Ждем завершения задачи
if task.done():
exception = task.exception()
if exception:
print(f"Задача завершилась с исключением: {exception}")
else:
print("Задача завершилась без исключения")
if __name__ == "__main__":
asyncio.run(monitor_task())