Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Online Activity: Debugging and Error Handling
In this activity, you are to carry a number of exercises that introduce you to the world of debugging and
error handling in ASP.NET using C#.
Copy the application T:\itk368\Lim\ASPNETapps\BankingWebApp to your H: drive.
Open the application above.
Enabling Debugging
Select from the menu Debug > Start Debugging (or click on the button on the toolbar). Note the
window about the Web.config file. Select the 2nd option (Run without debugging) and click OK.
Note that when the browser shows the Default.aspx page, you see a runtime exception and very little
information is divulged, on purpose. As given in the message, “The source code that generated this
unhandled exception can only be shown when compiled in debug mode.” One can add a "Debug=true"
directive at the top of the file that generated the error (i.e., <%@ Page Language="C#" Debug="true"
%>) or add <compilation debug="true"/> to the configuration file of your application, i.e., to the
Web.config file.
Also, “Note that this second technique will cause all files within a given application to be compiled in
debug mode. The first technique will cause only that particular file to be compiled in debug mode.”
Lastly, another note is that “Important: Running applications in debug mode does incur a
memory/performance overhead. You should make sure that an application has debugging disabled
before deploying into production scenario.”
Now, add a "Debug=true" directive at the top of the Default.aspx file and Start Debugging again (and
choosing to Run without Debugging one more time).
Observe that more details are given about the source of the error because the Debug attribute has been
set to “true.”
Now set Debug attribute to “false” and Start Debugging again. This time, choose to have the Web.config
file modified. Namely, allow for application level debugging to be set to true.
What do you see? The error page that does not divulge any details again. What can you conclude about
the precedence? Which one has higher precedence--page-level or application-level setting?
Remember the answer to this question!
Now remove the Debug attribute from the page and start debugging again. Note the app stops at the
statement that throws the exception. Click on Continue/Run button and you will see the detailed error
page on the browser again.
Tracing
Add the attribute Trace=”True” to your Default.aspx and Start Debugging again. Note that there is a
slew of information reported on the page, some of which have been studied and other will be discussed
in details later in the course. For example, the information on the request method, the
QueryString/Form collections, the times of the page events, the browser details, etc. is readily available.
Note that the trace information does NOT include code details, such as values of variables. To include
such details, add the following code segment (in bold) to your Default.aspx file. Note that the debugging
code that you add should only run if tracing is enabled. To ensure this, test for Trace.isEnabled,
shown below.
<% int grossPay = 100; int numOfHours = 0; if (Trace.IsEnabled) { Trace.Warn("grossPay = " + grossPay); Trace.Warn("numOfHours = " + numOfHours); } int hoursRate = grossPay / numOfHours; %>
Now, when run, you see the following additional info in the trace.
…
To store diagnostic trace information for each page request in a log, one must enable application-level
tracing by turning it on via the ASP.NET configuration menu.
When the pages open up, click on the “Application Configuration” link and then the “Configure
debugging and tracing” link. Finally, click on the “Capture tracing information” box.
To view the trace information log, use the Trace Viewer. Do this by opening the file Trace.axd in the
project root folder (e.g., http://localhost:9666/Default.aspx/Trace.axd, substitute in your own URL
here). Check out the trace produced and dumped into the log file.
Using VS2010 Debugger
The above means of debugging works well for small programs, for figuring out runtime errors, etc. When
dealing with larger programs, a powerful IDE is often a better tool. In this section, you get to experiment
with the debugger found in VS2010 IDE.
From the previous run, you should get an output listing that displays the account values after deposit,
withdrawal, and transfer transactions are performed. Observe the values for account #2 and note that
the withdrawal of $800 from the account is not successful as the balance remains at $1000. Also note
that the transfer from one account to another is not successful either.
You can also see the results of the attempted transactions in the Output console of the IDE (see window below). Note that since the app is not a Console app, you need to use a different means of writing to the Output console. Namely, use System.Diagnostics.Debug.WriteLine("Transaction Unsuccessful!"); You can see this statement in the BankAccount.cs class.
While you’re at the IDE, note also that you cannot edit the code while debugging is in session (note the
“lock” symbol next to the files).
If you wish to edit the code, you need to first stop debugging by clicking on the “Stop Debugging”
button. Click on the button now so that you can edit the code below.
We're now going to track down the cause of the problem using the debugger. Even though the code is
relatively simple, do not solve the problem just by looking at the code. The point of this exercise is to
learn how to use the debugger to track down the culprit. We want to step through the program one step
at a time, in order to figure out what is wrong with the code. To do this, we first set a breakpoint in the
code. A breakpoint is simply a flag that tells the IDE "Stop here when debugging."
To set a break point you go to the line of code that you wish to set it on and then click on the border on
the left. This will put a breakpoint (the red dot) on this line. Since the Withdraw method is the one that
does not yield the correct, it is a good place to start the debugging process. So, place a break point at
the method.
Now, click on the Start Debugging button again. Note that the app stops at the break point set.
“Step Over” the code by clicking on the button on the debugging toolbar.
Note that because a local variable “balance” is declared, it hides the instance variable “balance” from
the class. Thus, instead of comparing $800 against $1000, the figure is being compared to zero. Thus,
the “Transaction Unsuccessful!” message.
Stop debugging and fix the code by deleting the “double balance = 0;” statement. Now, remove
the break point on the Withdraw method (just click on the break point again will do the trick) and set
one on the Transfer method. When run (Start Debugging), step over the code until you get to the “if”
statement. Note that both the “amount” and “this.balance” have the same value ($200, which can be
seen from the Autos pane) but the relational operator used is “<” instead of “<=.” Note also one can
point to a particular variable of interest and observe its value (e.g., amount is 200).
Note on the use of 'this' reference: Notice that the Transfer method uses a reference called this. It
should be noted that the “this” reference always refer to the object that has invoked the method. In
simple words, it refers to the calling object (the one whose name appears in front of the dot in the
method call). In this particular example, one can use “balance” instead of “this.balance” as the use of
“this” is implied.
Stop debugging and fix the error by changing the 2nd relational operator to <=. Start debugging one
more time and note that the app is working just fine now.
Handling Exceptions and Errors
When coding, you should make sure that things that may break are actually “break-proof.” Namely, you
should provide exception handling code such that when such exceptions occur, your code can gracefully
handle the events. Consult many resources available in the library, the Web, etc. on this very important
topic for more information.
Go back to the Default.aspx file and change the int hoursRate = grossPay / numOfHours; statement
such that it contains the following exception handling code.
try { int hoursRate = grossPay / numOfHours; }
catch (DivideByZeroException e) { Response.Write("<br/><hr/>Can't divide by zero!<br/>"); } catch (Exception e) { Response.Write("An exception occurred!<br/>"); } finally { Response.Write("Use the finally clause to do last clean up ...<br/>"); }
Now, when run, observe that the exception is caught and the finally clause executed.
Handling Page-Level and Application-Level Errors
Page-Level
To add page-level error handling, create the Page_Error event handler in the Default.aspx file, as shown
below. The 1st statement transfers the error response to the named URL. The boolean value specifies if
QueryString/Form collections are to be cleared (true) or preserved (false). The 2nd statement indicates
that the error has been handled and thus be cleared.
protected void Page_Error(object sender, EventArgs e) { Server.Transfer("ErrorPage1.htm", true); Server.ClearError(); }
Create a dummy page called "ErrorPage1.htm" and include appropriate contents in the page. Note:
“You will want to be cautious when displaying detailed information to the end user of the application,
especially when the application is running on the Internet. A more appropriate action would be to
display a message to the user notifying them that an error has occurred, and then actually logging the
specific error details in the event log.” [http://support.microsoft.com/kb/306355]
Now, re-run the app. Note that the exception is now handled at the above error handler.
Application-Level
If an error is uncaught at the page level, it is propagated to the application level. To setup application-
level error handling, unlike page-level error handlers, you create the Global.asax file. (Go to Project >
Add New Item > select Global Application Class from the installed templates. Keep the name as
Global.asax. Open the file and you will see various empty application-level event handlers, including one
for handling errors.
Create the above Global.asax file and add the code below.
protected void Application_Error(object sender, EventArgs e) { Server.Transfer("ErrorPage2.htm", true); Server.ClearError(); }
Create a dummy page called "ErrorPage2.htm" and include appropriate contents in the page. Now,
comment out the Page_Error method in the Default.aspx.cs file and re-run the app. Note that the
exception is now handled at the above error handler.