Error Handling in Visual Basic.NET

I used to develop in Visual Basic before the .NET days.  To be honest, in some ways I preferred those tools.  They were far simpler, and rather than worrying about how to implement something, you were more concerned with the implementation itself.  Life seemed much simpler.  However, one huge bugbear was the error handling.  It was horrible, ugly and exceptionally difficult to develop a real good error handler.  I wasn’t a fan.  Then along came Visual Basic.NET and all that changed.  The concepts of .NET error handling were cough cough borrowed from Java, which borrowed them from Delphi (a great but now defunct language) which I’m sure borrowed it’s core concepts from elsewhere.  What is originality anyway?  Undetected plagiarism.

So, what is so good about Error Handling in Visual Basic.NET?    You may have heard error handling called exception handling?  No?  Well let me explain.  Errors occur in code.  We all make mistakes.  They may occur because of user error, because you didn’t anticipate something in your code, or just because you made a mistake.  It happens.  We’ve all seen applications or web sites break.   How can we help prevent them breaking?  By handling the errors and handling them gracefully.

Open project called “Select Case Statement”.   Run the project and when prompted to enter an age, enter the letter “e” and press “Younger or Older”.  What happens?  Your program went boom!  An error occurred, an unhandled error, so Visual Basic reported this to you and stopped running.

Look at the code in the button click event again

Dim age As Integer

age = CInt(TextBoxAge.Text)

Select Case age
     Case Is < 3
          MessageBox.Show("You are younger than Chris' niece")
     Case Is > 3
          MessageBox.Show("You are older than Chris' niece")
     Case Else
          MessageBox.Show("You are 3, the same age as Chris' niece")
  End Select</pre>

Why do you think it wouldn’t work?  Look at this line:

age = CInt(TextBoxAge.Text)

If you remember, the CInt function converts text into a number.  For example, it would convert “4” into 4.  However it has no idea what to do if you entered “e”.   There is no numeric value for “e”, so it raised an error.

I’m going to show you two ways to handle this error gracefully.

The first way would be to use a built Visual Basic Functions IsNumeric

Replace the click event code with this

Dim age As Integer

If Not IsNumeric(TextBoxAge.Text) Then
     MessageBox.Show("You must enter a number for your age", "Doh!", MessageBoxButtons.OK, MessageBoxIcon.Error)
     TextBoxAge.Focus()
     TextBoxAge.SelectAll()
     Exit Sub
End If

age = CInt(TextBoxAge.Text)

Select Case age

     Case Is < 3
          MessageBox.Show("You are younger than Chris' niece")

     Case Is > 3
          MessageBox.Show("You are older than Chris' niece")
     Case Else
          MessageBox.Show("You are 3, the same age as Chris' niece")
End Select

Run your code, enter “e” for your age.  What happens?  Your application warns you that the number isn’t numeric!  It works.  In addition, after the error, the invalid text was immediately selected.  You can edit the field immediately without clicking anywhere.  Nice!

So what is that code actually doing?

The first line of the new block is an IF Statement saying

IF Not IsNumeric(TextBoxAge.Text)

The IsNumeric Function will return true if the passed string is numeric.  False if not.  The line is essentially saying, if the string isn’t number, execute the code in the IF block.  Does that make sense?

Within the block there are 3 lines of code

MessageBox.Show("You must enter a number for your age", "Doh!", MessageBoxButtons.OK, MessageBoxIcon.Error)

This line will show a MessageBox telling the user  that they must enter a number for their age.  The Title of the Messagebox dialog is “Doh!”, I am instructing Visual Basic to put an OK button in the MessageBox and the Icon on the Messagebox is an Error symbol, or a big red cross.  Try experimenting with these parameters, Intellisense will show you what’s available.

Underneath that line the two lines

TextBoxAge.Focus()
TextBoxAge.SelectAll()

These lines instruct Visual Basic to put focus, ie the mousepointer on that textbox.  It also selects the offending text.  I hate it when applications don’t do this.  They force me to click on the offending area, select the offending number and write over it.  This guides the user’s attention and to the error and improves useability no end.  Feel free to use this technique liberally!

Finally the instruction

Exit Sub

Does what is says in the tin, it instructs Visual Basic to Exit the Sub without executing any more lines of code.

This kind of error handling is perfect.  You are anticipating the error before it happens and can handle the error very gracefully.  Often though, we aren’t so lucky.  We can’t anticipate everything, especially in a more complex app with many inputs and controls.  So what do we do?

Replace the click event code with this

Dim age As Integer

Try

     age = CInt(TextBoxAge.Text)

     Select Case age
          Case Is < 3
               MessageBox.Show("You are younger than Chris' niece")

          Case Is > 3
               MessageBox.Show("You are older than Chris' niece")
          Case Else
               MessageBox.Show("You are 3, the same age as Chris' niece")
End Select

Catch ex As Exception
     MessageBox.Show(ex.Message, ex.GetType().ToString())

Finally
     TextBoxAge.Focus()
     TextBoxAge.SelectAll()

End Try

I’ve removed the IsNumeric text and instead wrapped the entire code block in a Try Block.  This instructs Visual Basic to Try to execute the following code.  If an error occurs, the execution of code is immediately taken to the Catch block of code.   When an error occurs in Visual Basic, Visual Basic will create an Exception object.  Catch ex As exception will assign this Exception object to our variable ex.  The Exception object has a number of properties from which we can gleam what error occured.  We have utilised the Exception.Message property to display to the user.  We have also output the Type of Exception as the title of the Messagebox which will be worthwhile later in this tutorial.  There is far more detailed information using other properties in the Exception object that will provide more information on what went wrong.   Try experimenting with the other properties here.

The Finally block is then called.  There are two circumstances a Finally block will be called.  Either all the code in the Try block has been executed, or after the Catch code has been executed should an error be thrown.  In this Finally block I have set the focus back on the textbox and selected the text in there.

Run the project and try it, with valid or invalid values.  What happens?  With an invalid value you get the helpful error message of

Error handling in Visual Basic.NET

Huh?  Well hopefully you understand what its saying, it can’t convert the letter “e” to integer.  However imagine being an end user and reading that?  For the title of this MessageBox, I output the type of error that had occurred  - which turned out to be an System.InvalidCastException.

Replace the catch statement with this

Catch invalidCastException As InvalidCastException
    MessageBox.Show("You must enter a number for your age")

Catch ex As Exception
     MessageBox.Show(ex.Message, ex.GetType().ToString())

Run the code, enter the e and what happens?   The system is giving a much more user friendly error to the user.  Why?  Well we have two catch blocks.  One will catch all errors of type InvalidCastException, which we know will occur if the user doesn’t enter a number.  And another catch which will catch all other errors.  We can add as many different catch blocks as we like, but this catch all must go last in our catch blocks.

Which method of error handling do I prefer?  The first example of anticipating the error using the IF Statement, or the Try Catch Finally?  I would use a combination of both and depends on the circumstances.  Try Catches are absolutely essential in most enterprise apps – its physically impossible to anticipate all errors.   However often it’s often a lot more elegant to validate form contents, and predictable elements using the IF Statement.  Put thought into what makes the code more robust.  Don’t let your application break, and if an error occurs, try to tell your users exactly what s going on. Your users will love you for it!