Error Handling and Debugging in VB .NET

Error Handling and Debugging in VB .NET

Debugging your code is something you will need to do. Unless you write perfect code every time, there's no getting away from it. In this section, we'll take a look at ways you can track down errors using VB.NET.

 

Types of Programming Errors

Programming errors are generally broken down into three types: Design-time, Runtime, and Logic errors.

A Design-time error is also known as a syntax error. These occur when the environment you're programming in doesn't understand your code. These are easy to track down in VB.NET, because you get a blue wiggly line pointing them out. If you try to run the programme, you'll get a dialogue box popping up telling you that there were Build errors.

 

Runtime errors are a lot harder to track down. As their name suggests, these errors occur when the programme is running. They happen when your programme tries to do something it shouldn't be doing. An example is trying to access a file that doesn't exist. Runtime errors usually cause your programme to crash. If and when that happens, you get the blame. After all, you're the programmer, and you should write code to trap runtime errors. If you're trying to open a database in a specific location, and the database has been moved, a Runtime error will occur. It's your job to predict a thing like this, and code accordingly.

Logic errors also occur when the programme is running. They happen when your code doesn't quite behave the way you thought it would. A classic example is creating an infinite loop of the type "Do While x is greater than 10". If x is always going to be greater than 10, then the loop has no way to exit, and just keeps going round and round. Logic errors tend not to crash your programme. But they will ensure that it doesn't work properly.

 

Design Time Errors in VB .NET

Design time errors, remember, are syntax errors. It's when VB .NET hasn't understood what you have typed. If that isn't clear, a few examples should explain it beter. So do the following:

  • Create a new Windows project
  • Add a button and textbox to your form
  • Leave the Name properties on the defaults of Button1 and Textbox1
  • Double click your button to access its code, and type the following:

Textbox2.Text = "Debug"

When you finish typing the line, VB.NET puts a wiggly line under Textbox2:

VB code with wiggly line denoting an error

If you hold your mouse over Textbox2, you'll see a tool tip appear, like the following:

Not Declared error message

The error is occurring because you don't have a textbox called Textbox2. You'll also see this same "Not declared" error if you try to set up a variable on the fly (which you were allowed to do in previous version of VB.) As an example, change your code to this:

strText = "Debug"
TextBox1.Text = strText

Here, we're trying to put the word "Debug" into a variable called strText. We then want to assign this variable to the Text property of Textbox1. However, VB.NET protests about this, and puts a wiggly line under all occurrences of strText. Hold your mouse over the variable strText and you'll see the "not declared" tip again/

The problem this time is that we haven't declared the variable strText. Change the code to this:

Dim strText As String

strText = "Debug"
TextBox1.Text = strText

Now that we have declared a variable, the wiggly lines will go away. If we added the variable declaration in the wrong place, however, the wiggly lines would come back. Change you code to this:

strText = "Debug"
TextBox1.Text = strText

Dim strText As String

The wiggly lines will be back. That's because the declaration comes on the third line. When VB.NET meets the first two lines, it knows nothing about the strText variable.

If you have the Error List window open, you'll see a report of your error. (If you can't see the Error List window, from the menu bars click View > Error List.)

The Task List Window

Or this one, in later versions of Visual Studio:

Error List in Visual Studio 2017

If you still can't see the Error List box, have a look at the very bottom left of the software. Click on Error List:

Error List area

The description of the error is "Local variable 'strText' cannot be referred to before it is declared". If you double click the icons on the left, VB.NET will highlight the error in your code.

Move the Dim … Line back to the top, and not only do the wiggly lines go away, but the Task List will be erased.

Design-time errors like the one above can be quite straightforward to correct. Others can be quite difficult, and you'll see the wiggly line but not understand how to correct the error. The Task List should be your first port of call when faced with such an error.

 

Runtime errors in VB .NET

Runtime errors are a lot harder than Design Time errors to track down. As their name suggests, these errors occur when the programme is running. Runtime errors are the ones that crash your programme. A simple way to crash a programme is to divided by zero. Change the code for your button to this, and try it out:

Dim Num1 As Integer
Dim Num2 As Integer

Num1 = 10
Num2 = 0

TextBox1.Text = CInt(Num1 / Num2)

The CInt( ) part means Convert to an Integer. We're just making sure to convert the answer to the sum into a number. But run your programme and test it out. Click your button and see what happens.

What happens is that you'll get the following error message popping up:

The Overflow Error

If you have started your programme without debugging then the error message is a little less helpful:

Exception error message

Stop your programme from running to get rid of any error messages.

When you try to divide by zero, VB.NET throws up the Overflow error message - there would be just too many zeros to go into the Integer variable type. Even if you change the Type into a Single or a Double, you'd still get the same error message. Programming environments just don't like you dividing a number by zero. If this were in a real programme, chances are it would crash, or "bug out". And you'll get the blame!

 

If you think the answer to a calculation could result in zero, you should check for this. We'll see how to write code to trap Runtime errors in a moment. But here's another example of one.

From the controls toolbox, add a RichTextBox control to your form. Change the Name property of your RichTextBox to rt1. A RichTextBox is just like a normal textbox but with more functionality. One of these extra functions is the ability to load a file directly. Delete or comment out any code you have for your button, and add the following line:

rt1.LoadFile("C:\test10.txt", RichTextBoxStreamType.PlainText)

 

All the line does is to load (or try to) the text file called "test10.txt" into the RichTextBox. The second argument just specifies that the type of file we want to load is a Plain Text file.

Run your programme, and then click the button. If you don't have a text file called "test10.txt" in the root folder of your C drive, you'll get the following Runtime error message:

The File Not Found error message

You may see this smaller error box in Visual Studio 2017:

File Not Found error message in Visual Studio 2017

The additional information is quite useful this time. It's saying that the file "C:\test10.txt" could not be found. If the error occurred in a normal programme, it would shut down. Not something you want a programme to do in mid stream! But let's see how to deal with it.

We will take a look at Try ... Catch in order to trap any errors in your code.

 

Try ... Catch in VB .NET

VB.NET has a inbuilt class that deals with errors. The Class is called Exception. When an exception error is found, an Exception object is created. The coding structure VB.NET uses to deal with such Exceptions is called the Try … Catch structure.

In the coding area for your button, type the word Try. Then hit the return key on your keyboard. VB.NET completes the rest of the structure for you:

Try

Catch ex As Exception

End Try

The Try word means "Try to execute this code". The Catch word means "Catch any errors here". The ex is a variable, and the type of variable it is is an Exception object.

Move your line of code from the previous section to the Try part:

Try

rt1.LoadFile("C:\test10.txt", RichTextBoxStreamType.PlainText)

Catch ex As Exception

End Try

When you run your programme, VB will Try to execute any code in the Try part. If everything goes well, then it skips the Catch part. However, if an error occurs, VB.NET jumps straight to Catch. Add the following to your Catch part:

MessageBox.Show(ex.Message)

Your coding window should look like this:

Try ... Catch code in VB NEt

Because ex is an object variable, it now has its own Properties and methods. One of these is the Message property. Run your programme and test it out. Click your button. You should see the following error message:

File Not Found Error

The message is coming from the "additional Information" section of the error message we saw earlier, the one we didn't handle. But the point about this new message box is that it will not crash your programme. You have handled the Exception, and displayed an appropriate message for the user.

If you know the kind of error that a programme might throw, you can get what Type it is from the Error message box you saw earlier. This one:

The File Not Found error message

Or this, in Visual Studio 2017:

Exception error in Visual Studio 2017

Click the View Details links (under Actions, in earlier versions of Visual Studio). You'll see a box like this, in the 2017 edition:

QuickWatch dialogue box, Visual Studio 2017

Or this, in earlier versions:

Details about the error thrown by VB NET

The first line tells us the Type of Exception it is:

System.IO.FileNotFoundException

You can add this directly to the catch part. Previously, you were just catching any error that might be thrown:

Catch ex As Exception

But if you know a "file not found" error might be thrown, you can add that to the Catch line, instead of Exception:

Catch ex As System.IO.FileNotFoundException

You can keep the Exception line as well. (You can have as many Catch parts as you want.) This will Catch any other errors that may occur:

Try

rt1.LoadFile("C:\test10.txt", RichTextBoxStreamType.PlainText)

Catch ex As System.IO.FileNotFoundException

MessageBox.Show(ex.Message)

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

There is one last part of the Try … Catch Statement that VB.NET doesn't add for you - Finally:

Try

Catch ex As Exception

Finally

End Try

The Finally part is always executed, whether an error occurs or not. You typically add a Finally part to perform any cleanup operations that are needed. For example, you may have opened a file before going into a Try … Catch Statement. If an error occurs, the file will still be open. Whether an error occurs or not, you still need to close the file. You can do that in the Finally part.

But Microsoft advise that you always use Try … Catch Statements in your code. However, throughout the rest of this course, for convenience sake, we won't be using them much. Even when we should be.But that's no excuse for you not to use them!

 

Logic Errors in VB .NET

The third category of errors are the Logic errors. These can be thought of as coding errors. Your coding errors. They can be quite tricky to track down, and have you tearing your hair out with frustration. You will often hear yourself saying "But that should work! Why won't it!"

Add another button to the form tou created in the first part, and try this code as an example of a logic error:

Dim x As Integer
Dim y As Integer
Dim answer As Integer

x = 10.5
y = 3
answer = x * y
TextBox1.Text = answer

When you've added the code to your button, run your programme and test it out. Before you click the button, what answer did you expect to get?

You'd think that 10.5 multiplied by 3 would give you the answer 31.5. Click your button. The answer that appears in your textbox is 30!

 

This is a logic error: when you don't get the answer you thought you'd get. The problem, if you were paying attention during the variable types sections, is that we are trying to put floating point numbers into an Integer variable type. The Integer variable only works with whole numbers. When you assign 10.5 to the variable x, the point 5 on the end gets chopped off. So only the 10 gets stored in x. 10 times 3 is thirty, and this is the answer that appears in the textbox.

But the point is that VB.NET did not raise a Design-time error. Nor did it raise a Runtime error. The programme executed, and did not "bug out" on us. It just didn't give you the answer you expected - it was a logic error.

Logic errors can be fairly simple to track down and solve. (The problem above can be solved by changing the variable types from Integer to Single or Double.) But they can also be quite difficult to track down. Especially as your code gets longer and longer. Here's another example of a logic error.

Erase the code you have for button2, and add the following instead:

Dim i As Integer
Dim LetterCount As Integer
Dim strText As String
Dim letter As Char

strText = "Debugging"

For

i = 1 To strText.Length - 1
letter = strText.Substring(1)

If letter = "g" Then

LetterCount = LetterCount + 1

End If

Next

TextBox1.Text = "G appears " & LetterCount & " times"

All the code does is to try and count how many times the letter "g" appears in the word "Debugging". We're using a For loop, and Substring to get one letter at a time. This single letter is then placed inside the variable called letter. An If Statement is used to check if the letter is a "g". If it is, we increment the LetterCount variable. The answer we're expecting in the textbox is 3. Except, we don't get 3. We get zero:

The programme has not found the letter "G"

There were no wiggly lines and therefore no Build errors. When the button was clicked, a Runtime exception did not crash the programme. So that leaves a logic error. But where is it?

 

Breakpoints and Debugging Tools

In the last part, you added some code to a button. All the code does is try and count how many times the letter "g" appeared in the word "Debugging". We saw that the programme failed to do this, and came up with the answer zero. To help you find out what went wrong, there is a tool in VB .NET called a Breakpoint. Let's see what this is, and how to use Breakpoints.

 

VB NET Breakpoints

A breakpoint is like a note to VB.NET to stop your programme at a particular place. You add one to your code by clicking in the margins. A brown circled then appears, indicating where the code will break. The following two images show how to add one:

Click in the margins to add a Breakpoint

When you click in the margins, to the left of a line of code, a brown circle appears:

A Breakpoint has been added

Notice that the line where you want VB.NET to break is highlighted brown.

Run your programme, and click the button. You are immediately returned to the coding window. The place where you put the Breakpoint will now have a yellow arrow on top of the brown circle. The brown highlighted line will now be yellow:

The Breakpoint is now highlighted in yellow

The yellow highlight indicates where in your code VB.NET is. To continue checking your code, press F10 on your keyboard (you can also press F11, but this will jump into any Subs or Functions you've set up.)

The next line in your code will be highlighted:

The programme has advanced to the next line

The yellow arrow, and the yellow highlight, jump down one line. Press the F10 key again. Then hold you mouse on the letter variable. The value this variable currently holds will be displayed:

Hold your mouse over a variable

The first time round the loop, the value in letter is "e" (The "c" next to it means that the variable type is Character).

If the "e" of "Debugging" is getting checked first, what happened to the "D"? Straight away, this indicates a problem. And the problem is that the Substring method starts counting from zero. So halt your programme by clicking "Debug > Stop Debugging", or click the Stop icon on the toolbar. Change the line in question to this:

letter = strText.Substring(0)

Run your programme again, and click the button. When you are returned to your code, press the F10 key and check the value of the letter variable. It should now be this:

Hold your mouse over the variable again

This time, the code is catching the first letter of the word when the loop begins, and not the second one.

Is that it? Have we found the cause of our problems? Stop your programme. Click on the brown circle to get rid of the Breakpoint. Run it again, and see what happens.

 

The number of G's counted is still zero! So the logic error has not yet been tracked down. Create another Breakpoint at the same place, and try again.

You can continue pressing the F10 key until you've spotted the error. Or you can use another debugging tool - the Locals window.

While your programme is still in Debug mode (the yellow line will still be there, if it is), click Debug > Windows > Locals from the menu bar. You should see the following in the bottom left of your screen:

The locals window

Locals means "Local variables". That is, variables declared in this section of the code. The variables i, letter and LetterCount are showing in the window. The value of these variables is also displayed: 0, Nothing and 0. Press F10 and these values will change. This is the Locals window after one go round the loop:

Press the F10 key to advance the programme

The variable i is now 2; letter is "D", and LetterCount, is still 0. Keep pressing F10 and go round the loop a few times. What do you notice?

You should notice that the value in letter never moves on. It is "D" all the time. And that's why LetterCount never gets beyond 0.

Exercise J

Why does LetterCount never gets beyond 0? Correct the code so that your textbox displays the correct answer of 3 when the programme is run.

 

And that's it for Error checking and debugging. It can often be an art form in itself. But one well worth persevering with: it could save you a lot of headaches!

No more Reading online, CLICK HERE and get the full tutorial in MS Word Format!