Galileo Computing < openbook >
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung

...powered by haas.homelinux.net...

Einstieg in VB.NET von René Martin
- Für Programmiereinsteiger -
Einstieg in VB.NET
gp Kapitel 3 Fehler
  gp 3.1 Fehler abfangen
  gp 3.2 Programmierhilfen
    gp 3.2.1 IntelliSense
    gp 3.2.2 Automatische Hilfe
    gp 3.2.3 Automatische Prüfung
    gp 3.2.4 Der Zwischenablagering
    gp 3.2.5 Kommentare
    gp 3.2.6 Aufgabenkommentare
  gp 3.3 Fehlersuche im Code
    gp 3.3.1 Ergebnisse und Zwischenergebnisse
    gp 3.3.2 Haltepunkte
    gp 3.3.3 Das Lokalfenster
    gp 3.3.4 Das Überwachen-Fenster
    gp 3.3.5 Das Direktfenster
    gp 3.3.6 Einzelschrittmodus
  gp 3.4 Zusammenfassung

Kapitel 3 Fehler

In diesem Kapitel geht es um Fehler. Dabei gibt es zweierlei Themenbereiche: logische Fehler, die der Programmierer macht, und Fehler, die im Laufe des Programms auftreten, sei es durch falsche Benutzereingaben, sei es durch Fehler, die das System produziert. Erstere müssen gesucht werden, letztere können abgefangen werden.


Galileo Computing

3.1 Fehler abfangen  toptop

Dynamische Dialoge sind eine gute Hilfe, um den Benutzer zu führen: Er kann nur aus einer Liste auswählen, nur eine Zahl in ein Textfeld eingeben oder es sind gewisse Kombinationen gesperrt. Möglicherweise schafft er es aber dennoch das System zu überlisten oder die fehlerhafte Variante, die er eingibt, wurde von Seiten des Programmierers nicht bedacht.

Nehmen wir das Primzahlenbeispiel des letzten Kapitels: Der Benutzer gibt eine Zahl ein, klickt auf einen Button und es wird gemeldet, ob diese Zahl eine Primzahl ist oder nicht. Wenn er allerdings eine negative Zahl eingibt, kann keine Wurzel gezogen werden, was zu einer Fehlermeldung führt. Gibt er Text ein, erhält er ebenfalls eine Fehlermeldung.

Die Funktion IsNumeric wurde schon in den ersten beiden Kapiteln erwähnt, hier nun die vollständige Liste aller Funktionen, mit denen bestimmte Kriterien überprüft werden können:

Tabelle 3.1   Die Validierungsfunktionen
Funktion Bedeutung
IsArray überprüft, ob die Variable ein Array ist
IsDate überprüft, ob das eingegebene Datum gültig ist
IsDBNull überprüft, ob ein Wert DBNull ist. Dies wird für Datenbanken verwendet
IsError überprüft, ob ein Ausdruck ein Exception-Objekt ergibt
IsNothing überprüft, ob ein Ausdruck Nothing ist
IsNumeric überprüft, ob ein Ausdruck eine Zahl ist
IsReference überprüft, ob ein Ausdruck einen Referenztypen ergibt

Man könnte nun verschiedene Varianten abfangen. Das folgende Beispiel überprüft, ob nichts eingegeben wurde, ob Text, eine negative Zahl oder eine Dezimalzahl eingegeben wurde. Falls alle Tests negativ verlaufen, beginnt das eigentliche Programm.

If Me.txtZahl.Text = "" Then
   MessageBox.Show("Bitte geben Sie" & _
   " eine Zahl ein.")
ElseIf IsNumeric(Me.txtZahl.Text) = False Then
   MessageBox.Show("Der eingegebene Wert" & _
   " ist keine Zahl.")
ElseIf CDbl(Me.txtZahl.Text) < 0 Then
   MessageBox.Show("Der eingegebene Wert" & _
   " darf nicht negativ sein")
ElseIf CDbl(Me.txtZahl.Text) <> _
   Math.Ceiling(CDbl(Me.txtZahl.Text)) Then
   MessageBox.Show("Der eingegebene Wert" & _
   " muss ganzzahlig sein")
Else

   dblZahl = CDbl(Me.txtZahl.Text)
   For dblZähler = 2 To Sqrt(dblZahl)
      If dblZahl Mod dblZähler = 0 Then
...
Abbildung

Abbildung 3.1   Fehler werden abgefangen

Die Funktion Math.Ceiling ermittelt die nächst größere ganze Zahl, die größer oder gleich der eingegebenen Zahl ist. Also Math.Ceiling(2.8) ergibt 3, Math.Ceiling(8.1) ergibt 9 und Math.Ceiling(5) liefert 5.

Dieses Beispiel für das Abfangen der Eingabewerte mag bei einem kleinen Programm noch funktionieren, aber bei sehr großen, komplexen Programmen können bestimmte Fehlerquellen übersehen werden. Um auf alle Fehler, gleich welcher Natur, zu reagieren, stehen die Try ... Catch-Blöcke zur Verfügung. Die Syntax lautet:

Try
Anweisungen
Catch ex As Exception
Routinen zur Ausnahmebehandlung
Finally
Endanweisungen
End Try

Unser Primzahlenbeispiel könnte also wie folgt modifiziert werden:

Try
   dblZahl = CDbl(Me.txtZahl.Text)
   dblZähler = 2

   Do Until dblZähler > Math.Sqrt(dblZahl)
      If dblZahl Mod dblZähler = 0 Then
         MessageBox.Show(dblZahl.ToString & _
         " ist keine Primzahl" & vbCr & _
         dblZähler.ToString & "ist ein Teiler")
         Exit Sub
      End If
      dblZähler += 1
   Loop

   MessageBox.Show(dblZahl.ToString & _
   " ist eine Primzahl")
Catch ex As Exception
   MessageBox.Show(ex.Message)
End Try

Tritt ein Fehler nach der Zeile Try auf, dann wird die Zeile

Catch ex As Exception

angesprungen. Man könnte dort eine Meldung ausgeben »Es trat ein Fehler auf«, was allerdings nicht sehr geschickt ist.

Abbildung

Abbildung 3.2   Der Fehler wird abgefangen – allerdings ist die Anzeige nicht sehr aussagekräftig.

Das selbst definierte Objekt »ex« besitzt nun einige Methoden und Eigenschaften, mit denen differenziert auf den Fehler eingegangen werden kann. Die einfachste Möglichkeit, sich die Beschreibung des Fehlers anzeigen zu lassen, lautet »Message«. »Source« liefert das Objekt oder die Anwendung, welche den Fehler produziert hat.

Abbildung

Abbildung 3.3   Message zeigt den Fehler an.

»StackTrace« liefert Informationen über die Aufrufliste, die zu dem Fehler geführt hat. Praktisch hierbei ist, dass in der letzten Zeile die Nummer erscheint, welche den Fehler auslöst. Die Zeilennummern können über Extras Optionen Text-Editor Basic eingeschaltet werden.

Abbildung

Abbildung 3.4   StackTrace beschreibt den Fehler genau.

Abbildung

Abbildung 3.5   Die Zeilennummer ist für den Programmierer hilfreich. In Zeile 126 ist der Fehler aufgetreten.

Will man nun differenziert auf den Fehler reagieren, dann steht eine Reihe von Ausnahmeklassen zur Verfügung:

Tabelle 3.2   Die Liste der wichtigsten Ausnahmeklassen
Klasse Bedeutung
AccessException Fehler beim Zugriff auf eine Eigenschaft oder Methode
ArgumentException ein Argument ist ungültig
ArgumentNullException eine Methode erhält Nothing als Argument – sie akzeptiert es nicht
ArgumentOutOfRangeException das übergebene Argument liegt außerhalb des Gültigkeitsbereichs
ArithmeticException Unter- oder Überlauf
ArrayTypeMismatchException in einem Datenfeld wurde ein falscher Wert gespeichert
DivedByZeroException Division durch 0
FormatException Typen unverträglich
IndexOutOfRangeException Index außerhalb des gültigen Bereichs (beispielsweise bei Arrays)
InvalidCastException beim Umwandeln von einem Datentyp in einen anderen ist ein Fehler aufgetreten
NullReferenceException ein Objekt referenziert auf Nothing
OutOfMemoryException kein Arbeitsspeicher mehr zur Verfügung
StackOverflowException Überlauf

Soll nun nach einem abgefangenen Fehler eine Zeile abgearbeitet werden, geschieht dies mit Finally. Diese Technik ist beim Datenbankzugriff wichtig: Im Try-Block wird eine Verbindung zu einer Datenbank hergestellt. Angenommen, es kommt beim Datenaustausch zu einem Fehler – dann greift die Ausnahmebehandlungsroutine. In jedem der beiden Fälle (alles hat geklappt oder es trat ein Fehler auf) soll die Datenbankverbindung wieder geschlossen werden. Dies wird im Finally-Block erledigt. In unserem Beispiel macht es wenig Sinn, könnte aber wie folgt aussehen:

Try
   dblZahl = CDbl(Me.txtZahl.Text)
   dblZähler = 2
   Do Until dblZähler > Math.Sqrt(dblZahl)
      If dblZahl Mod dblZähler = 0 Then
         MessageBox.Show(dblZahl.ToString & _
         " ist keine Primzahl" & vbCr & _
         dblZähler.ToString & "ist ein Teiler")
         Exit Sub
      End If
      dblZähler += 1
   Loop

   MessageBox.Show(dblZahl.ToString & _
   " ist eine Primzahl")
Catch ex As FormatException
   MessageBox.Show("Eingabe falsch!")
Catch ex As DivideByZeroException
   MessageBox.Show("Nicht durch Null teilen")
Catch ex As Exception
   MessageBox.Show(ex.Message)
   MessageBox.Show(ex.StackTrace)
Finally
   dblZähler = 0
   dblZahl = 0
End Try
  

VB.NET

Einstieg in ASP.NET

Einstieg in C#

Visual C#

VB.NET und Datenbanken

Einstieg in XML