Foutafhandeling in asynchrone code
Veeg om het menu te tonen
Bij het werken met asynchrone code in Python met behulp van asyncio vereist het afhandelen van fouten extra aandacht, omdat uitzonderingen zich anders kunnen verspreiden dan bij synchrone code. In een synchrone context gebruik je vaak een try-except-blok om uitzonderingen op te vangen rond code die mogelijk kan falen. Dezezelfde structuur werkt binnen coroutines, maar er zijn extra aandachtspunten bij het werken met taken die door asyncio zijn gepland.
Als er een uitzondering wordt opgegooid binnen een async def-coroutine en deze niet wordt opgevangen, zal deze zich verspreiden tot het punt waar de coroutine wordt afgewacht. Als je await gebruikt op een coroutine die een uitzondering opwerpt, wordt de uitzondering op de await-locatie opgegooid, waardoor je deze kunt opvangen met een try-except-blok. Als je echter een coroutine als taak plant met asyncio.create_task() of asyncio.ensure_future(), wordt de uitzondering niet direct verspreid. In plaats daarvan wordt deze opgeslagen in het taakobject en zal alleen worden opgegooid wanneer je expliciet op de taak wacht of het resultaat controleert.
Dit betekent dat als je geen uitzonderingen afhandelt binnen de coroutine of bij het afwachten van de taak, je mogelijk kritieke fouten mist, of dat de uitzonderingen door de event loop worden gelogd als "unhandled exceptions". Om dit te voorkomen, moet je uitzonderingen afhandelen binnen de coroutine met try-except, of ervoor zorgen dat je alle taken afwacht en hun resultaten correct afhandelt. Deze aanpak helpt je asynchrone programma's stabiel te houden en maakt het debuggen eenvoudiger.
Hier is een Python-codevoorbeeld dat laat zien hoe je uitzonderingen binnen een asynchrone coroutine afhandelt met een try-except-blok:
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())
Verwachte uitvoer:
Caught exception in coroutine: Even number error: 0
Processed: 1
Caught exception in coroutine: Even number error: 2
Dit codevoorbeeld definieert een asynchrone coroutine may_fail die een try-except-blok gebruikt om ValueError-uitzonderingen op te vangen wanneer een even getal wordt verwerkt. Als n even is, wordt een ValueError opgegooid en binnen de coroutine opgevangen, waarbij een bericht wordt afgedrukt. De coroutine main plant drie taken met asyncio.create_task() en verzamelt ze met asyncio.gather(), zodat alle taken worden afgewacht. Deze opzet zorgt ervoor dat uitzonderingen die in de coroutines worden opgegooid, netjes worden afgehandeld en dat er geen niet-afgehandelde uitzonderingen in de event loop achterblijven.
Bedankt voor je feedback!
Vraag AI
Vraag AI
Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.