La gestione degli errori in VB .NET

Visual Basic .NET introduce un nuovo costrutto per la gestione degli errori, che va ad affiancarsi al classico On Error: si tratta di try… Catch… Finally, costrutto che risulterà sicuramente familiare a chi ha programmato in C++ o in Java. Esso consente di gestire gli errori che possono verificarsi in una certa porzione del codice, senza interrompere l’esecuzione del programma. La sintassi ad utilizzare è la seguente:

try
‘Codice che potrebbe generare un errore.
Catch
‘Codice da eseguire in caso di errore.
Finally
‘Codice da eseguire sia che si sia verificato un errore nel
‘blocco try sia che non ci siano stati problemi.
End try

In un costrutto try è necessario specificare almeno una Catch oppure una Finally; è possibile specificare più clausole Catch, una per ogni errore che si vuole gestire, mentre è consentito inserire solo una clausola Finally. Per uscire da un blocco try si deve usare l’istruzione Exit try.
Se si verifica un errore nel blocco try, si dice che il programma ha generato un’eccezione. Nella clausola Catch si può indicare il tipo di errore (eccezione) che si vuole gestire; ad esempio:

Catch ex As OverflowException

Specifica che si vuole catturare un’eccezione di overflow, che viene generata quando si cerca di assegnare ad una variabile un valore al di fuori del suo range. Si consideri il codice seguente:

try
Dim A As Byte = 100
Dim B As Byte = A * A
Catch ex As OverflowException
MsgBox(“Si è verificato un errore: ” & ex.Message)
End try

Le due variabili A e B sono di tipo Byte, quindi possono assumere valori tra 0 e 255. La prima istruzione del blocco try viene quindi eseguita senza problemi, mentre la seconda, che cerca di assegnare a B il valore A * A, cioè 10000, causa un’eccezione di overflow, che viene catturata dalla Catch sottostante. Se, invece di OverflowException avessimo specificato un altro tipo di eccezione, come IndexOutOfRangeException, il blocco Catch non sarebbe stato eseguito e sarebbe apparso il classico messaggio di errore di run-time di Visual Basic. L’oggetto ex, di tipo OverflowException, consente di recuperare varie informazioni sull’errore. Nel codice sopra riportato abbiamo usato ex. Message per conoscere la descrizione dell’eccezione.

Se si vuole avere un unico Catch in grado di gestire tutti gli errori, è possibile definire l’oggetto ex di tipo Exception, il tipo base da cui ereditano tutte le eccezioni. In alternativa è anche consentito omettere il tipo di eccezione che si vuole catturare (quindi scrivere solo Catch), ma in questo modo non si ha la possibilità di ottenere informazioni sull’errore. Supponiamo di essere in fase di chiusura di un programma e di avere alcune istruzioni che possono causare degli errori; per esemplificare al massimo immaginiamo che le istruzioni in questione siano quelle viste in precedenza, ovvero le assegnazioni dei valori alle variabili A e B. Se non siamo interessati a catturare questi errori, ma vogliamo che l’applicazioni termini in ogni caso, usando un costrutto try si deve scrivere:

try
Dim A As Byte = 100
Dim B As Byte = A * A
Catch
‘In realtà non si esegue nessuna operazione in caso di errori.
Finally
Me.Close()

In questo caso il blocco Catch non esegue alcuna operazione. L’uso della parola chiave Finally ci assicura che le istruzioni successive verranno sempre eseguite. Provate ad inserire questo codice nella routine che gestisce l’evento Click di un pulsante e ad eseguire l’applicazione: il programma terminerà correttamente anche se togliete l’istruzione di assegnazione a B.
Possiamo finalmente terminare il nostro editor di testi aggiungendo la gestione degli errori. Alla fine della precedente Lezione abbiamo accennato al fatto che gli errori possono verificarsi in fase di apertura o salvataggio dei dati. trattandosi di operazioni sui file, quindi, le possibili eccezioni sono tipo IOException. Modifichiamo le routine ApriFile e SalvaFile in modo da prevedere le situazioni problematiche: in caso di errore, vogliamo che venga semplicemente visualizzata una finestra di messaggio per informare l’utente del problema. Cominciando da ApriFile, dopo le modifiche il codice dovrebbe risultare il seguente:

Private Sub ApriFile(ByVal NomeFile As String)
Dim Testo As String
try
Dim FileReader As New System.IO.StreamReader(NomeFile)
‘Legge l’intero file e lo salva nella variabile “Testo”.
Testo = FileReader.ReadToEnd
FileReader.Close()
‘Libera le risorse allocate con New.
FileReader = Nothing
txtTesto.Text = Testo
Catch ex As System.IO.IOException
MsgBox(“Si è verificato un errore durante la lettura dal file: ” & ex.Message)
End try
End Sub

Tutto il codice che lavora con i file, essendo “a rischio”, è stato inserito all’interno di un costrutto try, in modo che un eventuale problema provochi l’esecuzione del blocco Catch. Con questa piccola modifica la routine ApriFile è in grado di gestire situazioni di errori senza terminare il programma. C’è però un’imperfezione nel nostro codice: se, ad esempio, l’errore si verifica nel metodo ReadToEnd, l’istruzione FileReader = Nothing, che libera le risorse allocate dall’oggetto FileReader, non viene eseguita. Per risolvere l’inconveniente, la prima idea che viene in mente è quella di ripetere tale istruzioni anche nel Catch; tale soluzione è corretta, ma non sfrutta a fondo le potenzialità del costrutto try. Abbiamo infatti detto che, specificando un blocco Finally, il relativo codice verrà eseguito sia in caso di problemi, sia nella normale esecuzione del programma. Usiamo quindi questa possibilità per assicurarci che l’istruzione FileReader = Nothing venga sempre eseguita. Per raggiungere il nostro scopo basta modificare la routine ApriFile in modo che risulti:

Private Sub ApriFile(ByVal NomeFile As String)
Dim Testo As String
Dim FileReader As System.IO.StreamReader
try
FileReader = New System.IO.StreamReader(NomeFile)
‘Legge l’intero file e lo salva nella variabile “Testo”.
Testo = FileReader.ReadToEnd
FileReader.Close()
txtTesto.Text = Testo
Catch ex As System.IO.IOException
MsgBox(“Si è verificato un errore durante la lettura dal file: ” & ex.Message)
Finally
‘Libera le risorse allocate con New.
FileReader = Nothing
End try
End Sub

Abbiamo dovuto spostare la dichiarazione dell’oggetto FileReader all’esterno del blocco try, perché altrimenti la sua area di validità era limitata alle istruzioni del blocco stesso, quindi non poteva essere utilizzata nel blocco Finally.
Le stesse modifiche vanno fatte alla routine SalvaFile, e sono quindi lasciate per esercizio.

Concludiamo così la realizzazione del nostro editor, che potete prelevare con un clic qui. Molte sarebbero le funzionalità ancora da implementare, ad esempio fare in modo che appaia un avviso se l’utente non ha salvato le modifiche di un file, aggiungere la stampa, ecc. Ad ogni modo, le caratteristiche base sono state ampiamente trattate nel corso delle ultime tre Lezioni, dando a tutti gli strumenti necessari per ritoccare il programma secondo la propria fantasia.

Con la prossima Lezione riprenderemo l’analisi dei principali controlli di Visual Basic .NET; in particolare, introdurremo il richiestissimo controllo NotifyIcon, che consente di visualizzare un’icona nella barra delle applicazioni di Windows, vicino all’orologio. Nella stessa Lezione discuteremo anche della realizzazione di un programma privo di interfaccia utente, utile, ad esempio, se si devono progettare applicazioni che rimangano costantemente in background nel sistema.

Both comments and pings are currently closed.

Comments are closed.