Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Gestione degli errori

Una fondamentale competenza di ogni buon programmatore
Una fondamentale competenza di ogni buon programmatore
Link copiato negli appunti

Uno degli aspetti fondamentali di un'applicazione scritta in modo corretto è una completa gestione degli errori. Saper intercettare esecuzioni non corrette o procedure che falliscono consente al programmatore di poter agire in modo rapido e tempestivo ed allo stesso tempo permette di fornire agli utenti un chiaro e rassicurante messaggio al posto di un più freddo e sconsolante errore generico.

Ma questo non è tutto. Una corretta gestione degli errori permette di rendere più sicuro un programma evitando di esporre ad un utente qualsiasi, quindi anche a potenziali hacker (o cracker), il risultato di un errore con informazioni tecniche che potrebbero essere usate per bypassare la sicurezza del codice.

Tipi di errori

Esistono sostanzialmente 3 principali tipi di errori.

Errori logici

Sono i più complessi da individuare poiché dipendono da errori di sviluppo del programma. L'esecuzione darà esito positivo ma non il risultato desiderato. Il saper prevenire errori logici è una capacità che si acquisisce nel tempo e rappresenta una delle caratteristiche fondamentali di un buon programmatore.

In questo caso né ASP né un qualsiasi altro linguaggio potranno offrire supporto per questi tipi di errori per i quali è invece utile una fase preliminare di test del programma.

Errori di sintassi

Sono gli errori più facili da individuare e da correggere poiché non è possibile eseguire una pagina fin tanto che sono presenti uno o più errori di sintassi.

Un esempio comune consiste nella mancata chiusura di un costrutto if ... else o nell'uso errato dei costrutti di iterazione, come ad esempio for ... loop invece di for ... next o ancora nella scrittura di termini errati come Reponse al posto di Response.

Errori di esecuzione

Rappresentano la categoria più ampia dei possibili errori di un programma e raccolgono qualsiasi errore generato durante l'esecuzione di una pagina ASP.

Sono errori di esecuzione una divisione di un numero per 0, l'accesso ad una posizione di un array non presente, l'uso di una variabile non dichiarata, errori alla connessione al database... e via dicendo.

In presenza di un errore di esecuzione il programma viene terminato e viene mostrato a video un messaggio corrispondente al primo errore generato.

Intercettare gli errori

Partendo dal presupposto che un errore di sintassi non permette l'esecuzione della pagina e che un errore logico non è gestibile da un computer, ciò che ci rimane da gestire sono gli errori di esecuzione ed è proprio questo quello che ASP ci consente di fare.

Abbiamo detto prima che al verificarsi di un errore in esecuzione il programma termina, mostrando un messaggio non troppo amichevole, tipo:

Microsoft OLE DB Provider for ODBC Drivers error '80040e10'
[Microsoft][Driver ODBC Microsoft Access] Parametri insufficienti. Previsto 1.
/attivita/index.asp, line 73

La prima cosa da fare è quindi evitare l'interruzione del programma.

Questo è possibile usando lo statement On Error Resume Next che forza il webserver a procedere l'esecuzione anche se vengono generati uno o più errori. La procedura che ha restituito l'errore verrà saltata e verrà eseguita la prima istruzione successiva corretta.

Inoltre, quando On Error Resume Next è attivo le informazioni su eventuali errori popoleranno l'oggetto Err che potrà quindi essere interrogato per scoprire maggiori dettagli sul problema.

Per tornare alla situazione di default è sufficiente dichiarare On Error Goto 0 ed automaticamente in caso di errore il programma si comporterà in modo predefinito, terminando l'esecuzione.

Gestire l'errore

Vediamo quindi come è possibile implementare questo sistema nelle nostre pagine ASP. Il modo più opportuno di procedere è quello di inserire il comando di proseguimento ad inizio della pagina e controllare dove necessario in fase di elaborazione che tutto proceda correttamente.

Se si utilizza la gestione degli errori è inoltre consigliato abilitare il buffer di elaborazione delle pagine che permetterà di mostrare il contenuto agli utenti solo se il processo è andato a buon fine, in alternativa sarà possibile svuotare la memoria di esecuzione e mostrare semplicemente il messaggio di errore.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%

' Abilita il buffer di esecuzione
Response.Buffer = true

' Abilita la gestione degli errori
On Error Resume Next

' Codice ASP della pagina
' [...]

%>
<html>
<head>
<title>Pagina</title>
</head>

<body>
<%

' Punto di controllo degli errori
if Err.Number <> 0 then

' Svuota il buffer di elaborazione
Response.Clear()

' Mostra un messaggio di errore
Response.Write("Si è verificato un errore in fase di esecuzione.<br>")
Response.Write("Tornare alla pagina precedente e riprovare.")

else

' Mostra il contenuto della pagina,
' il risultato dell'elaborazione o quanto desiderato.

end if

%>
</body>
</html>

Vediamo insieme l'esempio.

Ad inizio pagina con Response.Buffer = true viene abilitato il buffer che forza la visualizzazione della pagina al termine della elaborazione. In seguito attiviamo la gestione degli errori.

Le istruzioni successive saranno costituite dal nostro codice ASP che verrà eseguito come di consueto.

Arriviamo ora alla parte più interessante. Nel caso si generazione di un errore abbiamo detto prima che viene popolato l'oggetto Err che fornisce 4 proprietà:

  • Err.Number
    Numero dell'errore generato.
  • Err.Description
    Breve descrizione dell'errore.
  • Err.Source
    Sorgente del tipo di errore. Ad esempio ci informa se l'errore proviene da un recordset, database, da un calcolo...
  • Err.Line
    Informazioni sulla riga d'errore.

Usando queste proprietà possiamo quindi avere maggiori possibilità di intervento per risolvere il problema. Eseguendo ad esempio un controllo sul valore della proprietà Err.Number possiamo individuare se la pagina ha generato un errore, sapendo che in modo predefinito il suo valore è 0. Nel caso sia stato generato un errore svuotiamo il buffer dell'elaborazione e mostriamo un messaggio a piacimento.

In alternativa possiamo proseguire la nostra elaborazione mostrando il risultato delle istruzioni.

Esempi di gestione avanzata

Combinando le proprietà dell'oggetto Err prima descritte possiamo realizzare un vasto numero di controlli sul nostro codice. Vediamo alcuni esempi.

Risposta personalizzata

Sfruttando il numero di errore restituito possiamo immaginare di creare una serie di messaggi di errore diversificati da usare nelle nostre pagine.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%
' Abilita il buffer di esecuzione
Response.Buffer = true
' Abilita la gestione degli errori
On Error Resume Next
' Punto di controllo degli errori
if Err.Number <> 0 then

' Controlla l'errore
Select case Err.Number
Case "" ' numero errore
' messaggio personalizzato
Case "" ' altro numero errore
' altro messaggio personalizzato
Case else ' errore generico
' messaggio generico
End select

else
' Mostra il contenuto della pagina,
' il risultato dell'elaborazione o quanto desiderato.
end if

%>

In presenza di una struttura particolarmente ampia possiamo poi decidere di spostare la select case in un file da includere in tutte le pagine per costruirci una completa ed efficace gestione.

Indirizzare ad una pagina personalizzata

Un'altra idea molto diffusa è quella, in caso di errore, di indirizzare ad una pagina appositamente creata per gestirlo interrompendo così l'elaborazione della precedente.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%
' Abilita il buffer di esecuzione
Response.Buffer = true
' Abilita la gestione degli errori
On Error Resume Next

' esecuzione asp

' esempio
' stringa = 5/0

' Punto di controllo degli errori
if Err.Number <> 0 then

Response.Clear()
Response.Redirect("errore.asp?number=" & Err.Number & "&descr=" & Err.Description)

end if
%>

In questo esempio in caso di errore si viene indirizzati alla pagina errore.asp passando in querystring alcune informazioni sull'errore, ottenute tramite le proprietà .Number e .Description prima trattate.

Questo consente nella nuova pagina di stampare i dettagli del problema che non sarebbero recuperabili in altro modo dato che l'oggetto Err è valorizzato solo per la pagina in cui viene generato l'errore.

La pagina errore.asp potrebbe avere questa forma

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%

Response.Write("<p>Si è verificato un errore.<br>")
Response.Write("Nel caso il problema persista contattare il webmaster ")
Response.Write("fornendo i seguenti dettagli tecnici:</p>")
Response.Write("<p>Numero: " & Request.QueryString("number") & "</p>")
Response.Write("<p>Descrizione: " & Request.QueryString("descr") & "</p>")

%>

Nel caso si provi ad eseguire la divisione riportata come esempio (5 diviso 0) si verrà indirizzati alla pagina errore.asp che mostrerà a video un messaggio del tipo

Si è verificato un errore.
Nel caso il problema persista contattare il webmaster fornendo i seguenti dettagli
tecnici:
Numero: 11
Descrizione: Divisione per zero

Abbiamo così scoperto che la divisione per 0 corrisponde all'errore numero 11.

Inviare una email al verificarsi di un errore

Gli esempi di utilizzo della gestione, come detto in precedenza, potrebbero essere centinaia. Eccone uno conclusivo particolarmente utile. Consente, in caso di errore, di inviare una email ad un indirizzo stabilito fornendo i dettagli necessari per agire tempestivamente.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%
Response.Buffer = true
On Error Resume Next

' elaborazione ASP

if Err.Number <> 0 then

Response.Clear()

' Crea il contenuto dell'email
Dim strCorpo
Dim strOggetto

strOggetto = "Errore nel sito " & Request.ServerVariables("HTTP_HOST")
strCorpo = "Si è verificato un errore di esecuzione nel sito in oggetto."
strCorpo = strCorpo & vbCrLf & "Si è verificato un errore
di esecuzione."
strCorpo = strCorpo & vbCrLf & "Di seguito i dettagli."
strCorpo = strCorpo & vbCrLf & "Pagina: " & Request.ServerVariables("URL")
strCorpo = strCorpo & vbCrLf & "Numero: " & Err.Number
strCorpo = strCorpo & vbCrLf & "Tipo: " & Err.Source
strCorpo = strCorpo & vbCrLf & "Descrizione: " & Err.Description
strCorpo = strCorpo & vbCrLf & "Riga: " & Err.Line
strCorpo = strCorpo & vbCrLf & vbCrLf
strCorpo = strCorpo & vbCrLf & "Si raccomanda un tempestivo intervento!"

' Invio della email con l'oggetto CDONTS
Dim objMail

Set objMail = createObject("CDONTS.NewMail")
objMail.From = "errori@sito.com"
objMail.To = "errori@sito.com"
objMail.Subject = strOggetto
objMail.Body = strCorpo

objMail.BodyFormat = 1
objMail.MailFormat = 1
objMail.Send()
Set objMail = Nothing

' Mostra un messaggio all'utente
Response.Write("<p>Si è verificato un errore.</p>")
Response.Write("<p>Una email è stata inviata al supporto tecnico.</p>")
Response.Write("<p>Ci scusiamo per l'inconveniente.</p>")

end if
%>

Nell'esempio sopra al verificarsi di un errore vengono valorizzate alcune variabili, viene creato il contenuto dell'email con le informazioni dell'errore e la pagina in cui è stato generato.

In seguito l'email viene inviata ad un destinatario stabilito usando l'oggetto CDONTS. Ovviamente è possibile adattare questo codice alle proprie esigenze variando il contenuto dove necessario o costruendo l'invio dell'email con un oggetto alternativo in base alla configurazione del server, ad esempio CDOSYS.

Infine viene mostrato all'utente un messaggio personalizzato.

Ti consigliamo anche