Le Eccezioni
Un'eccezione altro non e' che un modo differente per indicare un errore
durante l'esecuzione di un programma. A differenza del'usuale gestione degli
errori, pero', le eccezioni prevedono dei costrutti piuttosto strutturati,
dentro quali individuare un tipo di errore ed intrappolarvelo. Con intrappolare
intendo: fare in modo che al verificarsi dell'errore, l'esecuzione del
programma venga trasferita proprio nel punto desiderato. Un eccezione
s'intrappola con un blocco Try...End Try, piu' esattamente nel
blocco Catch definito al suo interno. Se non e' intrappolata,
un'eccezione, viene comunque gestita dal sistema con un messaggio che, ahime',
causera' anche il termine dell'applicazione. Se invece la intrappoliamo,
possiamo gestire l'errore e proseguire con il programma, a patto che cio' sia
lecito, cioe' che l'errore non sia fatale.
In .Net un'errore e' impacchettato in un'eccezione che e' un vero e
proprio oggetto, contenente informazioni relative alle cause che l'hanno
prodotto. La classe Exception e' una classe base che
rappresenta un'eccezione generica. Da essa derivano tutte le eccezioni
specializzate per i vari tipi di errore che possono presentarsi. FileNotFoundException,
ad esempio, e' un eccezione che si presenta quando si tenta di accedere ad un
file che non esiste. Essa deriva direttamente da IOException che
e' la classe generica per tutti i tipi di eccezione di input/output. Ecco
l'albero di derivazione per questo tipo di eccezioni:
System.Object
System.Exception
System.SystemException
System.IO.IOException
System.IO.DirectoryNotFoundException
System.IO.EndOfStreamException
System.IO.FileLoadException
System.IO.FileNotFoundException
System.IO.PathTooLongException
Quando si verifica un errore, ci ritroviamo un oggetto di tipo Exception
che possiamo interrogare, tramite le sue proprieta', per esaminare cosa lo ha
causato. Ecco alcune proprieta' utili:
-
Message - Restituisce il messaggio che descrive l'errore.
-
Source - Il nome del programma o dell'oggetto che ha causato
l'errore.
-
StackTrace - Visualizza lo Stack al momento in cui si
e' verificato l'errore.
-
TargetSite - Indica il metodo che ha generato l'errore.
1) Al momento dell'errore si dice che viene lanciata un'eccezione. Noi
possiamo raccoglierla, esaminarla e prendere provvedimenti. L'esempio1 ci
illustrera' le cose:
Sub Esempio1()
Dim a As Decimal = 11
Dim b As Decimal = 0
Dim r As Decimal
Dim errori As Integer = 0
Try
r = a / b
System.Console.WriteLine("Il risultato e' " & r)
Catch e As DivideByZeroException
System.Console.WriteLine("errore")
errori += 1
Finally
System.Console.Write("Operazione eseguita con " & errori & _
" errori")
End Try
System.Console.ReadLine()
End Sub
In rosso, abbiamo marcato i vari blocchi che costituiscono la struttura con la
quale gestiamo un'eccezione. Questa e' la forma completa, avremmo potuto
omettere Finally.
Il blocco Try racchiude le righe di codice per le quali noi
vogliamo intrappolare eventuali eccezioni.
Il blocco Catch e' quello che intrappola l'eccezione il cui
tipo sia quello specificato come parametro dopo l'As . Da
qualsiasi punto del blocco Try, che generi un'eccezione del tipo
corrispondente, il flusso del programma passa a questa Catch.
Il blocco Finally e' quella parte di codice che viene comunque
eseguita, sia che si presenti un errore, sia che tutto vada bene. Potremmo
usarla, ad esempio, per chiudere un file, sia che un operazione di scrittura
sia andata in porto, sia che abbia fallito, magari per spazio insufficiente su
disco.
Nell'esempio, poiche' tentiamo di dividere a per b
e quest'ultima vale zero, si verifichera' un'eccezione. In particolare
l'eccezione DivideByZeroException.
2) Il prossimo esempio ci mostra come lanciare un'eccezione. A tale
scopo, utilizza l'istruzione Throw alla quale passiamo un
oggetto eccezione generico che etichettiamo con un messaggio custom.
Notate che avremmo potuto anche derivare una nostra classe personalizzata e
lanciarla al posto di Exception. La funzione Verifica
rappresenta un modo fantasioso per realizzare il confronto di un numero con
altro numero stabilito. Se i numeri non sono uguali viene lanciata
un'eccezione, altrimenti non succede niente. Se, pero', si verifica
l'eccezione, il blocco catch verra' eseguito e stampera' il messaggio d'errore.
Altrimenti l'esecuzione proseguira' normalmente e il messaggio "Ok" sara'
stampato. Soltanto se non occorre l'eccezione, la variabile booleana, indovinato,
verra' posta a true e quindi causera' l'uscita dal ciclo ed il termine
del programma.
Sub Verifica(ByVal x As Integer)
If x <> 5 Then Throw New Exception("Riprova")
End Sub
Sub Esempio2()
Dim indovinato As Boolean = False
Do
System.Console.Write("Indovina il numero: ")
Dim x As String = System.Console.ReadLine()
Try
Verifica(x)
indovinato = True
System.Console.WriteLine("Ok")
Catch e As Exception
System.Console.WriteLine(e.Message)
indovinato = False
End Try
Loop Until indovinato
System.Console.ReadLine()
End Sub
3) L'ultimo esempio ci mostra la possibilita' di usare blocchi Catch
multipli. Essi sono selettivi in base al tipo di eccezione che si genera nel
Try. Ognuno intercetta l'eccezione che gli compete. Si formano,
cosi', percosi multipli. La funzione attende l'input dell'utente. Due tipi di
errore possono verificarsi. Se l'utente digita un numero fuori dal range
0..255, si ha una OverflowException, perche' la variabile v e'
di tipo Byte. Se inserisce 0, otteniamo una DivideByZeroException,
e l'errore verra' gestito, in mancanza di una catch specifica, dalla catch per
un eccezione generica. Questo meccanismo e' possibile perche' tutte le
eccezioni derivano da quella generica.
Sub Esempio3()
Dim v As Byte
Dim d1 As Decimal = 1
Try
v = System.Console.ReadLine()
d1 = d1 / v
Catch eo As OverflowException
System.Console.WriteLine("Overflow")
Catch e As Exception
System.Console.WriteLine(e.Message)
End Try
System.Console.WriteLine("premi invio")
System.Console.ReadLine()
End Sub
Ultimo aggiornamento 13/01/2004
|