Menu
Coddy logo textTech

Cos'è la gestione delle eccezioni?

La gestione delle eccezioni è il modo in cui un programma reagisce agli errori che si verificano durante l'esecuzione. Il codice che potrebbe fallire va in un blocco protetto, come try, e quando viene sollevato un errore il controllo salta a un gestore, come except o catch, invece di andare in crash.

Di Kevin Spektor, Cofondatore e CTO

Aggiornato il 24 settembre 2026

Un programma che chiede l'età alle persone prima o poi riceverà "twenty" invece di 20. Convertire quel testo è un errore di runtime: int("twenty") solleva ValueError, e senza un piano per gestirlo il programma si ferma. La gestione delle eccezioni è quel piano. Delimiti il codice che potrebbe fallire e scrivi il codice da eseguire se succede.

Next year you will be 35
Not a number: twenty
Next year you will be 20
Done

La risposta sbagliata viene segnalata, e il ciclo prosegue con la successiva. Senza il try, il programma avrebbe stampato una riga e poi un traceback.

Come funziona la gestione delle eccezioni

  1. Il codice dentro try viene eseguito normalmente.
  2. Un'operazione fallisce, e il runtime solleva un'eccezione: un oggetto con un tipo (ValueError) e un messaggio (invalid literal for int() with base 10: 'twenty').
  3. Il blocco try si ferma a quella riga. Le righe rimanenti vengono saltate, ed è per questo che "Next year you will be" non viene stampato per "twenty".
  4. Il runtime confronta il tipo dell'eccezione con ogni clausola except, dall'alto verso il basso, ed esegue la prima che corrisponde.
  5. Quando il gestore finisce, il programma continua dalla prima riga dopo l'intera istruzione try.
  6. Se nessuna clausola corrisponde, l'eccezione esce dalla funzione corrente e la ricerca continua nella funzione che l'ha chiamata, poi in quella che ha chiamato quest'ultima. Si chiama svolgimento dello stack delle chiamate (stack unwinding). Se la ricerca arriva in cima al programma senza trovare corrispondenze, il programma termina con un traceback.

Il passo 6 significa che il gestore non deve per forza trovarsi nella funzione in cui avviene l'errore. Qui il fallimento avviene due chiamate più in profondità, e il gestore in fondo lo cattura comunque:

parsing 4.50
parsing free
Could not add the prices: could not convert string to float: 'free'

float("free") è fallito dentro parse_price. Né parse_price né total avevano un gestore, quindi sono state abbandonate entrambe, e "3.20" non è mai stato analizzato. Questa è la principale scelta di progettazione che la gestione delle eccezioni ti offre: gestire un errore dove sai cosa farne, che spesso è lontano da dove è successo.

try, except, else e finally

L'istruzione try di Python ha altre due parti facoltative. else viene eseguito solo quando il blocco try è terminato senza eccezioni. finally viene eseguito in ogni caso: dopo un successo, dopo un'eccezione gestita, e perfino quando la funzione fa return dall'interno del try.

no error
finally runs either way
2.0
b was zero
finally runs either way
None

finally è il posto per il codice di pulizia: chiudere un file, rilasciare un lock, chiudere una connessione al database. In Python l'istruzione with fa questa pulizia automaticamente per i file, ed è la scelta abituale in quel caso.

Sollevare eccezioni proprie

Le eccezioni non servono solo per gli errori che il linguaggio rileva. Quando una tua funzione riceve un input con cui non può lavorare, può sollevare un'eccezione per rifiutarlo, e chi la chiama decide cosa succede dopo. Definire una piccola classe di eccezione dà all'errore un nome che lo descrive.

70
Refused: cannot take 250, balance is 100

Python usa raise. Java, C++ e JavaScript usano throw per la stessa cosa.

La gestione delle eccezioni in altri linguaggi

LinguaggioParole chiaveDa sapere
Pythontry, except, else, finally, raiseOgni eccezione è un oggetto che eredita da BaseException
Javatry, catch, finally, throw, throwsLe eccezioni controllate come IOException vanno catturate o dichiarate con throws
C++try, catch, throwNiente finally; i distruttori fanno pulizia mentre lo stack si svolge
JavaScripttry, catch, finally, throwGli errori nel codice async si catturano con try attorno ad await
CnessunaLe funzioni restituiscono un codice di errore, e molte impostano errno
Gonessuna per gli errori ordinariLe funzioni restituiscono un valore error che il chiamante controlla

Lo stesso esempio di conversione in Java è così:

try {
    int age = Integer.parseInt("twenty");
    System.out.println(age + 1);
} catch (NumberFormatException e) {
    System.out.println("Not a number: " + e.getMessage());
} finally {
    System.out.println("done");
}

Java divide le eccezioni in due gruppi. Le eccezioni controllate (checked), come IOException, descrivono problemi fuori dal controllo del programma, e il compilatore si rifiuta di compilare codice che non le cattura né le dichiara. Le eccezioni non controllate (unchecked), sottoclassi di RuntimeException come NullPointerException, di solito indicano un bug, e il compilatore non ti obbliga a gestirle.

Errori comuni

  • Catturare tutto. Un except: senza tipo in Python cattura anche KeyboardInterrupt, quindi Ctrl+C smette di funzionare, e except Exception: cattura bug che non avevi mai previsto. Cattura il tipo specifico che sai come gestire.
  • Ingoiare l'errore. except ValueError: pass nasconde il problema. Come minimo, stampa o registra cosa è andato storto.
  • Un blocco try troppo grande. Avvolgi solo le righe che possono sollevare l'eccezione che stai catturando, così un errore che non c'entra non viene gestito per sbaglio.
  • Catturare i bug invece di correggerli. Un IndexError causato da un ciclo che fa un passo di troppo è un errore nel codice. Gestirlo tiene in vita il codice sbagliato.
  • Aspettarsi che catch fermi un crash in C o C++. Un segmentation fault è un segnale del sistema operativo, non un'eccezione, e su Linux e macOS un catch (...) di C++ non lo vede mai.

Cosa leggere dopo

Gli errori a cui risponde la gestione delle eccezioni sono descritti nella pagina sull'errore di runtime, e il crash che non può catturare nella pagina sul segmentation fault. Per la sintassi completa, leggi le guide alle eccezioni in Python, a try e catch in Java, alle eccezioni in C++ e a try e catch in JavaScript. Il corso Java e il corso Python le mettono in pratica con esercizi reali.

Domande frequenti

Quali sono le 5 parole chiave della gestione delle eccezioni in Java?
try, catch, finally, throw e throws. try delimita il codice da tenere d'occhio, catch gestisce un tipo specifico di eccezione, e finally esegue il codice di pulizia che si sia verificata un'eccezione o no. throw solleva un'eccezione, e throws nella firma di un metodo dichiara quali eccezioni controllate il metodo può passare a chi lo chiama.
Come funziona la gestione delle eccezioni in C++?
C++ usa try, catch e throw. Si può lanciare qualsiasi tipo, ma per convenzione si lancia un oggetto derivato da std::exception, come std::runtime_error, e lo si cattura per riferimento: catch (const std::exception& e). C++ non ha finally; la pulizia avviene nei distruttori, che vengono eseguiti automaticamente mentre lo stack si svolge.
Qual è la differenza tra un errore e un'eccezione?
Nell'uso quotidiano, un errore è qualsiasi cosa vada storta e un'eccezione è l'oggetto che un linguaggio usa per segnalarlo. Java traccia una linea più netta: Exception copre i problemi che un programma può ragionevolmente gestire, mentre Error, come OutOfMemoryError o StackOverflowError, segnala un guasto della JVM che di solito un programma non dovrebbe provare a catturare. In Python, ValueError e ZeroDivisionError sono entrambe eccezioni nonostante il nome.
Qual è la differenza tra throw e throws in Java?
throw è un'istruzione che solleva un'eccezione in quel punto: throw new IllegalArgumentException("negative age");. throws fa parte della dichiarazione di un metodo ed elenca le eccezioni controllate che il metodo può passare a chi lo chiama: void load() throws IOException. Il compilatore obbliga poi ogni chiamante a catturare quell'eccezione o a dichiararla a sua volta.
La gestione delle eccezioni rende il codice più lento?
Entrare in un blocco try costa poco nella maggior parte dei linguaggi moderni. Da Python 3.11, un try non costa quasi niente quando non viene sollevata alcuna eccezione, e i principali compilatori C++ non aggiungono costi di esecuzione al percorso in cui non viene lanciato niente. Sollevare e catturare un'eccezione è molto più lento di un test if, quindi nei cicli dove le prestazioni contano controlla i casi comuni invece di affidarti alle eccezioni.
Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA