VB.NET: Error handling for beginners - Part one, kinds of errors and methods for error handling.
A small tutorial for the beginner on error handling in VB.NET. This - part one - looks at the kind of errors there are and what methods we have to deal with them. Part two goes a little further in handling run time errors with "Try - Catch".
So, you're working in VB2005 or VB2008 and get errors from time to time?! Why not just quit making them.

Just kidding, but really, even if this is a tutorial on how to handle errors you can avoid a lot of them by validating user input and check for strange situations before errors occur. On the other hand there is (almost) no error free code. What we want to achieve while coding isn't error free code, it's code that is good enough, code that also takes care of the cases where it isn't good enough. I know some people - much better coders than I - will be upset by this state of mind but the truth is (as I see it) that as soon as you have code that's beyond trivial you'll have errors. I believe this is due to the fact that in many cases there's only one correct way and many many wrong ways - it's impossible to foresee everything and you will end up with errors. So lets handle them.
Errors can be categorized in three groups:
1) Syntax or coding errors.
2) Logical errors.
3) Run time errors.
1) Syntax or coding errors are generally handled by the IDE or the compiler, they are not that big a problem. If the code compiles without errors or warnings there are (probably) no syntax errors in it. In order to get some help catching syntax and coding errors always use "option explicit on" and "option strict on", they should be set in the project property page and they should be written in every code file.
2) Logical errors are the worst. The code compiles, it runs smoothly and all is fine. The only problem being that the results are wrong since the logic is wrong.
An example could be that I intended to convert a temperature in degrees F to a temperature in degrees Celsius: C = (F - 32) * 5/9 but while coding I made a mistake and came up with: C = F * 9/5 + 32 which is actually the way to convert Celsius to Fahrenheit. My program would run and look good but rockets might explode and peoples homes would become baking ovens.
These errors are nasty - you have to check the result of your code against known data. In this example I should check what result I got, e.g. for the freezing and boiling point of water in degrees F and degrees C and compare it to data from a good source such as a physics handbook.
To avoid logical errors you could think of tests before you code. Reason with yourself.
* What am I supposed to achieve here?
* How can I check that my program, procedure or statement matches the goal?
* Test that your code does match the goal! Check your results against another source if possible.
3) Run time errors are the ones that throw up ugly signs telling the user that an "Un handled exception has occurred" - something that surely will reduce trust in your program even if the user gets the opportunity to keep the program running.
Lets look at an un handled error. Copy and paste the following code into a new form, replacing the code that's there. Build and execute the program. This will present you with an error.
CODE
Option Explicit On
Option Strict On
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim counter As Integer, sum As Integer
sum = 0
For counter = 1 To 1000000
sum += counter
Next
End Sub
End Class
The code creates an overflow exception since after several times through the for-loop the sum is so big it won't fit in an integer. If you run this in your IDE you'll get an informative box telling you what kind of error has occurred and what you might think of to correct it. Getting this error in runtime just throws up an ugly message box that is quite intimidating to the user.
How do we take care of these errors? Well there are two really different methods.
3.1) Unstructured error handling using "On Error GoTo"
3.2) Structured error handling using "Try - Catch"
3.1) The ON ERROR approach exists in both VB6 and VB.NET and is also known as unstructured error handling. Seldom used in .NET.
I will not go into unstructured error handling much, but I'll show how it can be (mis-)used. Replace your current Form1_Load procedure with the following, make an exe (as above) and run it.
CODE
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim counter As Integer, sum As Integer
On Error GoTo ErrorSloppy
sum = 0
For counter = 1 To 1000000
sum += counter
Next
ErrorSloppy:
'This is where we land in case of any error.
'Put your error handling code here.
MsgBox("This is where we land in case of an error.")
End Sub
Nice, huh? The error is caught and everything is great. But wait! What if there is no error? Well, you'll get the error message in that case too - try commenting out the line
sum += counter. Avoiding this would - in this example - require that you use the dreaded despicable GoTo... Need I say more? What would happen if we had two possible error sources in the code? Well... Both would end up in the ErrorSloppy section. We would not have any obvious way of dealing with different errors.
There are situations where unstructured error handling using "On Error GoTo" is great, better than structured error handling. There are also ways to differentiate between errors. Despite this I won't talk more about it since it has many downsides and easily leads to sloppy coding. Just don't use it unless you know why you want it instead of structured error handling.
3.2) The "Try - Catch" approach which is used in many languages, also known as structured error handling.
Structured error handling, or the "Try - Catch" method, is easy to understand and straight forward. It's the most commonly used method for dealing with errors.
Let's take care of the above error in a structured way.
CODE
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim counter As Integer, sum As Integer
sum = 0
Try
For counter = 1 To 1000000
sum += counter
Next
Catch ex1 As exception
MsgBox("There's an error")
End Try
End Sub
This might not look so fantastic or different from the unstructured way. You will get a hint that something is different by commenting out the line
sum += counter. You see, no error message - since there is no error. What if we had two possible error sources in this code? Well... We would just wrap each of them in their own "Try - Catch"-block, like this.
CODE
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim counter As Integer, sum As Integer
sum = 0
Try
For counter = 1 To 1000000
sum += counter
Next
Catch ex1 As exception
MsgBox("There's an error")
End Try
sum = 0
Try
For counter = 1 To 1000000
sum += counter
Next
Catch ex1 As exception
MsgBox("There's a second error")
End Try
End Sub
The code above is pretty dull but it shows that we're able to handle errors where they are created. This comes in handy in a lot of situations like e.g. in distinguishing file not found errors from user input errors.
Remember that we are talking about errors! Do not use error handling instead of checking the data before you use them. Error handling is about taking care of situations that you can not know about and also about having a very last resort when you have missed to check things in your code that you ought to have checked.
This tutorial in short:
1) Syntax errors: Use option strict on and option explicit on.
2) Logical errors: Design tests for your code before coding. Verify the results of your code.
3) Run time errors: Use primarily to catch errors that are beyond your control, e.g. file not found.
3.1) Unstructured: "On Error GoTo" Use if you have a good reason.
3.2) Structured: "Try - Catch" Commonly used, usually the best way. Do NOT use instead of validation.
This is it for now about error handling. I'll get on to a second part as soon as possible. The second part will go a little deeper in to structured error handling with "Try - Catch".
More on error handling at Microsoft.Have a day!
/Jens
This post has been edited by jens: 23 Feb, 2009 - 04:56 AM