In Python, la gestione delle eccezioni è implementata attraverso le strutture try/except/else/finally e l'operatore raise.
try definisce un blocco di codice protetto. Se all'interno si verifica un'eccezione, il controllo passa al blocco except più vicino. Se non ci sono eccezioni, viene eseguito il blocco else, se presente. Il blocco finally viene sempre eseguito, indipendentemente dal fatto che ci sia stata o meno un'eccezione (ad esempio, per liberare risorse).
L'operatore raise genera esplicitamente un'eccezione o ripete quella corrente (nel blocco except senza specificare il tipo).
Esempio:
try: x = 1 / 0 except ZeroDivisionError as e: print(f"Errore: {e}") else: print("Non ci sono errori") finally: print("Sempre eseguito")
Risultato:
Errore: division by zero
Sempre eseguito
Finezze:
Domanda: «Cosa succede se in entrambi i blocchi try e finally si lancia raise con eccezioni diverse?»
Risposta: L'eccezione da finally "sovrascrive" l'eccezione da try: all'esterno uscirà quella generata da finally.
def foo(): try: raise ValueError("in try") finally: raise IndexError("in finally") try: foo() except Exception as e: print(repr(e)) # Stampa: IndexError('in finally')
Storia
Nel processo ETL, la connessione al database veniva sempre chiusa nel blocco finally, ma si dimenticava che all'interno di finally potrebbe verificarsi un'eccezione (ad esempio, se la connessione era già chiusa). Risultato — un'eccezione "nascosta" da finally assorbiva completamente l'eccezione dal codice principale, complicando drasticamente il debugging.
Storia
Utilizzavano catene di più except: da un generico except Exception sopra i particolari. Di conseguenza, tutti i specifici except rimanevano "morti" — le eccezioni a livello inferiore non venivano catturate separatamente, rendendo difficile la gestione degli errori specifici.
Storia
In un servizio web, nel blocco except si dimenticava di propagare l'eccezione ulteriormente attraverso "raise", registrando l'errore, ma permettendo al flusso di continuare. Di conseguenza, gli errori reali venivano "persi" e il programma continuava a funzionare in uno stato non corretto.