Come gestire correttamente le eccezioni in Python asyncio?

👤 Iniziato da @celestinolombardi
📅 26/03/2026 23:00
📁 Programmazione 🌐 IT
Avatar di celestinolombardi
Ciao a tutti, sono alle prese con un problema di gestione delle eccezioni in un progetto Python 3.10 basato su asyncio. Sto sviluppando un'applicazione che scarica file in parallelo usando async/await, ma non riesco a catturare correttamente gli errori di rete (es. timeout, connessioni rifiutate) in alcuni casi specifici. Ecco uno snippet del codice:

```python
async def download_file(url):
try:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.read()
except aiohttp.ClientError as e:
print(f"Errore rete: {e}")
return None
```

Il problema è che quando la rete è assente del tutto (es. disconnessione), l'eccezione non viene catturata e l'applicazione crasha. Il traceback segnala: "aiohttp.client_exceptions.ClientConnectorError: [Errno 101] Cannot connect to host...". Ho provato ad aggiungere blocchi except generici o da socket, ma senza risultati.

Usando asyncio.gather() per aggregare i task, forse devo gestire diversamente le eccezioni a livello superiore? Sto usando VSCode su Windows 11, con aiohttp 3.9.2. Qualcuno ha esperienza con questi errori persistenti o sa come isolare meglio i task per evitare crash? Grazie!
Avatar di druinamariani5
Ciao @celestinolombardi, il problema è che `ClientConnectorError` è una sottoclasse di `ClientError`, quindi in teoria dovrebbe essere catturato dal tuo blocco `except`. Tuttavia, a volte l'eccezione viene sollevata prima ancora che la sessione venga creata, quindi il `try` non la intercetta.

Prova a spostare il `try-except` all'esterno della creazione della sessione, così:

```python
async def download_file(url):
try:
async with aiohttp.ClientSession() as session:
try:
async with session.get(url) as response:
return await response.read()
except aiohttp.ClientError as e:
print(f"Errore durante la richiesta: {e}")
return None
except Exception as e:
print(f"Errore generale (es. connessione): {e}")
return None
```

Inoltre, con `asyncio.gather()`, puoi passare `return_exceptions=True` per evitare che un'eccezione faccia crashare tutto. Se vuoi gestire ogni task singolarmente, usa `asyncio.create_task()` e gestisci le eccezioni nel task stesso.

Per esperienza, a volte aiohttp si comporta in modo strano con le reti instabili. Se il problema persiste, potresti valutare di usare `httpx` con `AsyncClient`, che ho trovato più stabile in casi simili.
Avatar di celestinolombardi
Ciao @druinamariani5, grazie per la risposta dettagliata! Spostare il `try-except` fuori dalla sessione è stato illuminante: finalmente ho capito perché certe eccezioni mi sfuggivano. Il consiglio su `return_exceptions=True` l’ho provato e funziona, ma ho ancora un dubbio: se volessi gestire ogni task singolarmente con `create_task()`, come applico il blocco `except` a ciascun task senza appesantire il codice? Per ora resto su aiohttp, ma prendo nota di `httpx` se le cose si complicano. La tua soluzione ha sistemato il 90% del problema, ma vorrei togliermi l’ultimo sassolino dalla scarpa…

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!