Debugging & Error Handling
One of the fundamental truths of organized systems is that the more complex they become, the more likely they are to go wrong. While most of the examples we've looked at so far in this book have been quite simple, the principles behind OOP and the .NET framework are aimed at making it easier for you to build larger, more complex applications – after all, this is where you're most likely to make your money as a developer. Once you have planned and created your program, the steps involved in ensuring that your code runs smoothly at all times can be broken down into two main categories:
; Debugging – However hard we try to write flawless code, mistakes are always going to creep in.
We can minimize their effect by identifying those areas of our solution that are most error prone,
and adhering to good coding practices to make the errors more obvious.
; Error Handling – Even if the code itself is flawless, there's no guarantee that everything will go
according to plan when we come to use it. We have to anticipate all kinds of runtime errors, and
know what to look out for when things go wrong, so we can set about putting them right. On top of
this, we also have to be aware of errors that can stem from the environment in which our application
is run – such as the network connection or power supply failing, and anticipate how we will handle
This chapter will provide information to help you to identify problems, fix them, and prevent them occurring in future. We'll look specifically at the following topics:
; Different types of errors that can occur
; Good coding practice
; Identifying potential errors
; Locating errors in the page
; Handling Exceptions
; Handling errors
; Notifying and logging any errors that have occurred
A Few Good Habits
Whether you're an expert developer, or a beginner developing your first application, it's important to realize that you can significantly reduce the probability of an error occurring, by adopting some very straightforward habits. Finding an error in your application shouldn't be a cue to panic – it should be your cue to plan a way to fix the problem. This chapter covers information that will help you to define a plan of action when an error occurs.
Before we go into detail about the different kinds of errors that might occur in your page, let's talk about the preparations you can make to reduce the time it takes to identify and fix an error:
; Understand your code – The most important factor in finding a cause for an error, is to understand
the code. You should be able to identify the various sections of the code, such as presentation logic
containing different controls, business logic containing various functions, and so on, and be able to
say whether they are executed either client-side or server-side. A good understanding of the various
sections of the code in your page will help you locate the cause of an error. Internal comments and
documentation can be invaluable when doing this.
; Identify where it might break – Before even loading the page and testing its functionality, identify
the potential problem areas. For instance, say you have developed a page that communicates with a
database and pulls a set of records with specific information. To do this, you first create a
connection to the database, and then execute a query to retrieve the records. A potential trouble spot
for errors is in the lines where you create the connection, or in which you create the query. We will
discuss different kind of errors later in this chapter, which will assist you in looking out for
potential problems at an early stage.
; Amend identified error conditions – Once you have identified areas that could break within your
page, the next step is to make sure the conditions under which your error might occur are as stable
as possible. Remember the old adage, "prevention is better than cure".
So what can we learn from the above three steps? Mistakes in your code are not the end of the world. What matters is how quickly you can identify them and provide a fix. With that in mind, let's start with a look at the different kinds of errors that can occur.
As the name suggests, this type of error occurs when there is a problem in the syntax of the code. This will, most likely, be the first type of error that you'll encounter when developing ASP.NET pages. It might occur for one of the following reasons:
; A typo or bad grammar in the code syntax. For example, instead of typing
creating a text box control in your page, you type
; Incorrect code syntax. For instance, when creating a text box control, we might forget to close the
tag as shown below:
When it should actually be:
Debugging & Error Handling
; Combining or splitting keywords between languages. This is an error that I make quite a lot. If you switch
coding between JScript.NET and VB.NET, you encounter it even more often. A good example is the elseif
keyword. So what is that correct syntax? It depends on the language you are using. In VB.NET, the correct
syntax is elseif, whereas in JScript.NET the correct syntax is else if.
; Not closing a construct properly. This error occurs if we forget to close a construct, such as a
for...next, or a nested if...then...else...end if statement. Take a look at this, for
If condition1 then 'do this else if conidtion2 then 'do this if condition2a then 'do this else 'do this end if
Did you catch the error in the above code? An end if is missing. Imagine how difficult it would be to
spot this if we had the above code block set amongst hundreds of other lines of code.
These are just a few common examples of syntax errors. There is no way we could provide a list of all possible syntax errors that you might encounter, but the good news is that syntax errors are usually easy to find and fix.
The error page, which is the page that will be returned to you when you try to access an ASPX page with syntax errors using your browser, will provide information about the suspected error and the line number the error has occurred in. Let's have a look at an example of this error message.
1. Use your favorite editor to type the following lines of code. Let's make a spelling mistake (or typo)
when creating the textbox control, as shown below:
2. Save this file as syntaxerror.aspx and load the file using a browser. We're expecting to see a
textbox in the browser, as shown in the figure below:
What we actually see however is:
Debugging & Error Handling
How It Works
As the error message clearly states, the ASP.NET parser points to line 7, and asks us to check the details. When we look through the line, we can see that we have a spelling mistake: Tetbox, which should, of course,
be TextBox. If you correct the spelling mistake, and re-run the code, you will see the results as shown in the first figure.
Errors of this kind are very common, and are usually quick and easy to fix, since the error message provides a detailed breakdown of the error and the line on which it occurs.
The second type of error is the "Logical Error", and unfortunately, they are relatively difficult to find and fix. As the name implies, this kind of error occurs due to a mistake in the programming logic. The following are
some of the more common reasons for this type of error:
; Division by zero – This is an infamous error that has been around since the days of valve-based
computers. This error occurs when your program ends up dividing a number by zero. But why in the
world are we going to divide a number by zero? In most cases, this occurs because the program
divides a number by an integer that should contain a non-zero number, but for some reason, the
integer contains a zero. For instance, this could happen if you do not use the Explicit setting in
your program and make a spelling mistake in the variable name that is in the denominator. This
results in a logical error.
; Type mismatch – Type mismatch errors occur when you try to work with incompatible data types,
and inadvertently try to add a string with a number, or store a string to a variable of date datatype. It
is possible to avoid this error by explicitly converting the data type of a value before operating on it.
We will talk about variable data type conversion later in this chapter.
; Incorrect output – This type of error occurs when you use a function, or a subroutine, that returns a
different output to what you are expecting in your program.
; Use of a non-existent object – This type of error occurs when you try to use an object that was
never created, or an attempt to create the object failed.
; Mistaken assumptions – This is another common mistake that we make, which could be corrected
during the testing phase (if one exists). This type of error occurs when the programmer uses an
incorrect assumption in the program. For instance, a program that adds withdrawal amounts to a
current balance, instead of subtracting them.
; Processing invalid data – This is type of error occurs when the program is accepting invalid data.
An example of this, would be a library checkout program that accepts a book's return date as
February 29th, 2001, in which case, you may not have to return the book for a while!
While this is far from being an exhaustive list of possible logical errors, it should give you an feel for what to look out for when testing your code.
These are errors that are generated by ASP.NET itself. They may be due to malfunctioning code, a bug in ASP.NET, or even one in the Common Language Runtime. Although you could find this type of error, it is
usually not possible to fix the problem – particularly if it is an ASP.NET or CLR error.
Other errors that can be placed in this category are those that arise due to the failure of a web server or component, a hardware failure, or a lack of server memory.
Good Coding Practice
Now that we have an overview of the different kind of errors we're likely to encounter, let's consider some of the ways in which we can help to prevent them happening. It may not be feasible to expect perfect, totally error-free programs, but there are some precautions we can take to reduce or avoid the most common mistakes. Indent your code
This is quite an obvious and straightforward step. Although it won't ensure an error free program, this will really help to improve the readability of your code, either for yourself or for others. Remember, the syntax error that occurred because of a missing end if in a nested if...then...end if block? Indenting your code will help
you in finding those kinds of errors quickly. The following example lays out the code we used in our Syntax error Try It Out, above, in two different ways. See the difference for yourself:
Use sensible naming conventions – and stick to them
Naming conventions are useful, but only when applied consistently. Identify a suitable convention, and stick to it throughout your application. A common practice is to use first three letters of the name to denote the data type, followed by the actual variable name. Try to avoid using variables like i, j, tmp, or temp, as they are not very
descriptive. For instance, in the following code block, we use the two variables, i and j:
Dim i,j For i= 1 to 10 For j= 1 to 20 'do this next next
Debugging & Error Handling
In the following code block, we call our variables intClassCounter and intStudentCounter
respectively. The name you give a variable should explain what it's used for; in this example, they are clearly identifiable as counters for classes and students:
Dim intClassCounter as integer, intStudentCounter as integer
For intClassCounter= 1 to 10 'loop through 10 different class For intStudentCounter = 1 to 20 'do something next next
Comment your code
Here's another good, and easy, technique. This task also aids readability of the code. Commenting code goes hand in hand with the variable naming convention. Believe me, code you have written will look extremely confusing, even to you, after a period of time (maybe a few weeks or months). Writing comments with your code will help you remember exactly what your code is doing, which will be invaluable when you try to debug the code after a period of time.
Structure your code
Use subroutines and functions in your code to implement specific tasks. This is even more important for tasks that are used several times in your applications. For instance, consider a situation when you need to format the display of a date. The database might store a date in the form "CCYYMMDD", whereas you need to display it on the screen as "MM/DD/CCYY". We could then create a subroutine, such as the one shown below:
Public Sub FormatDate(CCYYMMDD) Dim intYear, intMonth, intDay intYear = left(CCYYMMDD,4) intMonth = mid(CCYYMMDD,5,2) intDay = right(CCYYMMDD,2)
response.write (Cstr(intMonth) &"/"& Cstr(intDay) &"/"& Cstr(intYear)) End Sub If you need to format the display of your date at different places in your program, you can simply call this sub to format the display, rather than writing in the whole process over and over again. Not only does this saves us time; if there's an error in the code (or we need to change it), we only need to change our sub code once. Use the Page Explicit setting
One of the options we can set in the Page directive at the top of an ASPX is as follows:
<%@ Page language="VB" runat="server" explicit="True" %>
If you set explicit to True and try using a variable that hasn't been defined, you'll find that your code raises an error. This can actually save you falling foul of a various logical errors that might have occurred because of a typo in the variable name – otherwise, these are very hard to find. For instance, take a look at the following code:
Dim DepositAmount, AccountBalance AccountBalance = 5000 ' the initial balance is $5000 DepositAmount = 2000 ' Customer deposits $2000 'adding the deposit to the balance to get the new balance AccountBalance = AccountBalance + DepostAmount
You expect to see the new account balance as $7000, but actually the balance will still be $5000. This is
because the variable DepositAmount is misspelt in the line it is added to the AccountBalance. This will
raise an error if explicit is used, since DepositAmount variable is not defined.
Use the Page Strict setting
This is another level of protection that you can opt for, also set from the Page directive:
<%@ Page language="VB" runat="server" strict="True" %>
Use of this setting will prevent any implicit type conversion that results in a data loss. Convert variables to the correct data types
Converting the values provided in your web page to an appropriate data type before using them in your program will
prevent Type Mismatch errors when we're using the Strict setting. For example, if the user provides "12.23" for a numeric field for which you're expecting an integer, assigning this value to the integer variable will result in an error. To
prevent this error, convert the value entered to an integer before assigning it to a variable of integer datatype. We could
use one of the following conversion functions provided by VB.NET:
Conversion Function Return Datatype
The following line shows the syntax for using this conversion function:
blnCondtion = CBool(varSomeVariable) ' Converts to a Boolean intNumber = CInt(varAnotherVariable) ' Converts to an Integer
Or, we could use the Convert class in the System namespace provided by the .NET framework. The following shows the syntax of using the ToString method of the Convert class.
StrSomeVariable = Convert.ToString(intSomeInteger) 'Convert Integer to String
Debugging & Error Handling
All these techniques can be used to help standardize and improve the readability of your code. A great many basic errors can thus be avoided. However, even if you do apply all these suggestions, your code still can't be guaranteed bug-free. In the next section, we're going to look at how to thoroughly test your code and (if necessary) fix it before it goes into a production environment.
Try to break your code
So, we've developed an application, and done our best to minimize the occurrence of the bugs we've described above. What's next? The next step is to test your code, in order to isolate and fix any errors that might occur once it's in the public domain.
We can break down our testing strategy into two main approaches: ; Being nice to your program – Supply your program with legal values, or values that your program is
designed to expect and handle. For instance, if your program contains an age field, supply only
numbers, not letters. Watch how your program behaves – does it respond as your expect it to with
the legal values you're supplying it?
; Try to break your program – This is the fun part. Supply your program with illegal values. For
instance, in our age field example above, you could provide AF as the value. This ensures that your
program handles all illegal values appropriately. Depending upon the kind of data you are expecting
in your program, you might have to do anything from a simple numeric, or alphabetic, check to a
validity check (such as inserting invalid dates into a date field).
Trapping invalid data
Testing your code by supplying both legal, and illegal, values is necessary for the proper functioning of your program. Your program should return expected results when providing legal values, and handle errors when supplied with illegal values. In this section, we'll talk about ways to handle the illegal values supplied to your program. We have two objectives here: ; Prevent the occurrence of errors that may leave you with many disgruntled users
; Prevent your program accepting and using illegal values, such as .10 for the age field
There are two main techniques that we can use to fulfill these objectives: manual trapping and validation. Manual trapping
When building our application, we could create error traps to catch illegal values before they get into the page processing, where they might halt the execution of the page, or provide invalid results. How do we block illegal values from sneaking in to page processing? Let's develop a page that accepts order quantity from the user.
1. Type the following code into your editor:
<%@ Page language="VB" Debug="true" %>
Order" Text="Complete Order" onclick="CompleteOrder" runat="server"/>
2. Save this file as manualtrapping.aspx.
3. Now load this file using your browser. The following figure shows the result of providing an order
quantity of 10:
Try supplying different values to the order quantity text box and verify if the page behaves as expected. 612