Published: 13 Aug 2007
By: Kazi Manzur Rashid
Download Sample Code

Shows how to create an effective error logging system in ASP.NET AJAX.

Introduction

In this article I will show you how to create an effective error logging system to log all kinds of JavaScript errors. Prior the release of ASP.NET AJAX we used some wonderful components like Microsoft Enterprise Library and Log4net to log all our application exceptions. Since the release of ASP.NET AJAX, a fair amount of code has been transferred to the browser, from the web server. We need a powerful logging system to catch all kinds of errors in the browser as well as record them in the server, in order to improve our application. In this article, I will provide an exception logging system developed with ASP.NET AJAX.

Design

I have been a great fan of Microsoft Enterprise Library and effectively implemented it in all of my projects since its release. My favorite part of Exception Handling in Enterprise Library is having the support for multiple trace listeners to log the same exception. By default, it has prebuilt trace listeners like Text File, EventLog, Email, Database, MSMQ. The real beauty is that you can write your own custom trace listener and easily plug it in the Enterprise Library. We will follow the same design concept in our logging system. We will not be able to get features like Text file, EventLog, as our logging system will be running in the browser instead of the server. We will use different sets of listeners like Alert, Debug, Div and WebService. Let's explore the Object Model of our logging system. The diagram shows the .NET Classes because I've generated the class diagram in Visual Studio; the actual JavaScript objects look the same.

Figure 1: Class Diagram

ClassDiagram.jpg

The main entry point of the logging system is the ExceptionManager class - a Singleton object. We will use the PublishException method of this class to log our exceptions. The ExceptionManager holds a list of trace listeners to which it delegates the call. We can add/remove listeners by calling the AddListener and RemoveListener methods of this class. To create a new listener, all we have to do is create a new class- which inherits from BaseTraceListener- that we will examine in the Extensibility section of this article.

Usage

Now let us explore the usage part. First, you have to add the Ajax.Logging.ExceptionManager.js file in the ScriptManager of your page like the following:

Next, add a script tag after the ScriptManager and add your preferred listeners in the Sys.Application load event, like the following.

Now we are all set to log our exception. Let's look at a few quick examples of logging.

Listing 3: Logging Regular Exception

Listing 4: Logging ASP.NET AJAX Exception

Listing 5: Logging Web Service Exception

Listing 6: Logging Update Panel Exception

Listing 7: Logging Unhandled Exception

ExceptionManager

As mentioned before, this is the main entry point of the logging system. It holds a list of listeners which it delegates the PublishException calls. Before delegating, it calls a helper method called GetEnviornmentInfo to gather various info such as the current url, a list of script tags with external source files, referrer, which are passed to individual listeners. The following listing shows the code for the PublishException method.

We are first ensuring that the exception passed is a JavaScript Error or a WebServiceError object. This is an interesting thing I found when working with client exceptions. The ASP.NET AJAX framework throws a different object (not a JavaScript Error) when a Web Service error occurs. On the other hand, in case of an Update Panel error it throws the regular JavaScript Error object.

BaseTraceListener

This is an abstract class from which all other trace listeners inherit from. It expects a line separator as a parameter (The default value is '\n') in its constructor. It also contains a helper method called FormatException that the other listeners call.

SysDebugTraceListener

It uses the Sys.Debug.traceDump method of the Microsoft Ajax Library to log the exception. Therefore, you must declare in the page a textarea element whose id is set to TraceConsole to allow this listener to work. Note that this listener will not work if the debug mode of the website in the web.config file is set to false. The following figure shows a screenshot of this listener in action.

Figure 2: SysDebugTraceListener in action

SysDebug.jpg

AlertTraceListener

This listener shows a message box with the error details. It shows more details comparing to the partial page rendering error box. The following figure shows a screenshot of this listener in action.

Figure 3: AlertTraceListener in action

Alert.jpg

DivTraceListener

This is similar to SysDebugTraceListener, but it writes the exception in an HTML div tag instead of a predefined element. The constructor of this class expects a div element or the id of that div.

Figure 4: DivTraceListener in action

Div.jpg

WebServiceTraceListener

This is the most important trace listener compared to the formers. It actually glues the client side errors with the server side exception recording. Along with the exception, it sends the url, the referrer (if available), a list of JavaScript files that are embedded in the page and its loading status. Since the server can discover many other important things of the request like the user name, authentication type, cookies collection, I have excluded these from sending. The server can also use the previously mentioned Enterprise Library, or Log4net to perform further processing. You can even write your own custom logic to record these exceptions.

Extensibility

In this section, I will show you how to create a custom trace listener using the Ajax Control Toolkit's Modal Popup to show the Error. If you are new to Modal Popup, I recommend that you browse the Ajax Control Toolkit site. You will also find some cool examples that use the Modal Popup in this link. The following figure shows a screenshot of the custom listener in action.

Figure 5: Custom listener using the Modal Popup

ModalPopup.jpg

Now let's move to the implementation part. First, declare the following style sheet in your page. This will be used for the popup background.

Next, add an ASP.NET Panel:

We are showing a generic error message and we are also providing a collapsible div, which shows the actual error message upon clicking the link. Next, add a Modal Popup like so:

We are also using few helper JavaScript functions to collapse/expand the error details div as well as hiding the Modal Popup when the Continue button is clicked. Let's see these functions.

Now, add a JavaScript file in Visual Studio by clicking on Add New Item and copy the following code:

We are also passing two additional parameters in the constructor: The id of the modal popup (or the modal popup itself) and the collapsible div ID (or the div itself). Next, when the PublishException method is invoked, we are calling the base class FormatExeception method to get the formatted details of the exception. Then, the formatted details are displayed through the div's innerHTML property. Finally, we call the show method of the modal popup.

Now let's find how we can integrate this new trace listener into our logging system. First, add a ScriptManager in the page. Then, reference the previous JavaScript file along with the Ajax.Logging.ExceptionManager.js file, like so:

Next, add a script tag after the ScriptManager and add this listener in the Sys.Application load event handler, as we did before.

Few key points

Throughout this component, I have used errorCode when logging the exception. The reason is, unlike the .NET Framework, in JavaScript there is no way to find the exact location and the other details of the exception. Using errorCode will help us to pin point the exact cause and location of this exception. Therefore, it is recommend to use different error codes for each exception. Maybe you can create a list of constants with these error codes as I did in the default.aspx page in the attached sample.

Another interesting thing I found when working with client exceptions is, when a server side exception (Web Service, Update Panel) is generated you will find the actual exception message, type, stack trace of that exception in JavaScript. Once you set the customErrors mode to On in the web.config file (recommended) when deploying the website, you'll obtain the generic message "There was an error processing the request" and no exception type and stack trace. I think this is unfortunate; at least the exception message and type should be present on the client side. May be the ASP.NET AJAX Team will consider this in future release.

Summary

Certainly there are many places where we can enrich the logger, such as routing an exception to predefined listeners (instead of all) or encapsulating it in a server side component so that the developer can easily configure it without writing a single line of code. Maybe I will implement those in the next version of this component. However, it will give you a good start in hunting the exceptions of your application.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Kazi Manzur Rashid

Kazi Manzur Rashid, Nickname Amit is a Diehard fan of Microsoft Technology. He started programming with Visual Basic 5.0 back in 1996. Since then he has developed many diversified solutions in his professional career, which spans from Anti-Spyware Tool to Personalized Start Page. Currently He is wor...

This author has published 10 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Animating a Web Form using ASP.NET AJAX
In this article you will learn how to animate a webform using asp.net ajax.
Jquery Ajax
JQuery makes communicating with the server very, very easy. JQuery uses get(), getJSON(), and post(...
jQuery Deferred Objects Promise Callbacks
jQuery Deferred/Promise objects untangle spaghetti-like asynchronous code.
jQuery in Action 2nd edition: Queuing functions for execution
This article is taken from the book jQuery in Action, second edition. This segment shows how you can...
Test120Jan
This is my custom article

You might also be interested in the following related blog posts


Introducing Recurring Appointments for Web.UI Scheduler ASP.NET AJAX read more
DevReach Follow-up, Part I read more
Make SharePoint 2007 Act Like SharePoint 2010, Updated read more
Gaia Ajax 3.6 Alpha released: Ajax GridView and Adaptive Rendering ++ read more
RadScheduler for Silverlight learning series, part 4: So what is RecurrenceExceptionHelper? read more
Exception Handling Advice for ASP.NET Web Applications read more
The "Error creating window handle" exception and the Desktop Heap read more
Read only classes and fields read more
AJAX Logging with Exponential Backoff read more
Telerik Introduces Free Web Testing Framework for ASP.NET AJAX and Silverlight read more
Top
 
 
 

Please login to rate or to leave a comment.