Wednesday, September 19, 2007 3:48 AM
kazimanzurrashid
New Project - Asp.net Ajax Exception Logging
In August Ajax column of DotNetSlackers, I have shown an effective exception logging system. In that column, I concluded saying that a lot of enhancement can be done with it which I finally did and created a project in CodePlex - Asp.net Ajax Exception Logging. Here is the list of enhancements:
- A new Control is introduced - ExceptionManager which is used to register the listeners. No need to manually register those.
- Automatic Logging of Unhandled and Update Panel Exceptions not need to hook those events manually. Just turn on the HandleUnhandledException and HandleUpdatePanelException which is by default turned on.
- Encapsulating listeners in its own server side class.
- An Enhanced version of web service listener which includes dynamic location of web service path/method name and batch submitting of exceptions.
- A built-in web service to log exceptions - ExceptionLogService.
- Introducing provider model in server side, so you can roll your provider to log these exceptions.
- Built-in provider which logs in Asp.net HealthMonitoring/WebEvents.
Let me give a quick tour.
Registering Listeners
Earlier you have to register the listeners like the following:
function applicationLoad(sender, args)
{
var mgr = Ajax.Logging.ExceptionManager.getInstance();
mgr.addListener(new Ajax.Logging.WebServiceListener());
mgr.addListener(new Ajax.Logging.PanelListener($get('pnlExceptions')));
mgr.addListener(new Ajax.Logging.SysDebugListener());
mgr.addListener(new Ajax.Logging.AlertListener());
}
Now you will do it in the server side:
<AjaxLogging:ExceptionManager ID="TheExceptionManager" runat="server">
<Listeners>
<AjaxLogging:WebServiceListener ServicePath="~/ExceptionLogService.asmx" ServiceMethod="Log" />
<AjaxLogging:PanelListener Panel="pnlException" />
<AjaxLogging:SysDebugListener />
<AjaxLogging:AlertListener />
</Listeners>
</AjaxLogging:ExceptionManager>
It will automatically inject the earlier JavaScript codes in the client side.
Handling Unhandled and Update Panel Exception
Previously you have to manually hook those events to log exceptions, now it will automatically log those exceptions, just ensure you did not turned off the HandleUnhandledException and HandleUpdatePanelException. You can also set the exception code from the server side .The Control will automatically inject the following code:
window.onerror = function(message, url, lineNumber)
{
var e = Error.create(message, {description:message, name:'UnhandledError', lineNumber:lineNumber, url:url});
Ajax.Logging.ExceptionManager.getInstance().publishException(105000, e);
return true;
}
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(AjaxLoggingHandleUpdatePanelError)
function AjaxLoggingHandleUpdatePanelError(sender, args)
{
var e = args.get_error();
if (e != null)
{
Ajax.Logging.ExceptionManager.getInstance().publishException(105001, e);
args.set_errorHandled(true);
}
}
Encapsulating Listener in Server Side Class
Now each of the listener is encapsulated in its own server side class. You can also roll your own listener from Inheriting the BaseListener class. For example, the following shows the code of AlertListener:
public class AlertListener : BaseListener
{
[Browsable(false)]
public override string CreateScript
{
[DebuggerStepThrough()]
get
{
string script = string.Format(System.Globalization.CultureInfo.CurrentCulture, "Ajax.Logging.ExceptionManager.getInstance().addListener(new {0}());", this.GetType().FullName);
return script;
}
}
[Browsable(false)]
public override IEnumerable<ScriptReference> ScriptReferences
{
[DebuggerStepThrough()]
get
{
return new ScriptReference[] { new ScriptReference(Owner.Page.ClientScript.GetWebResourceUrl(this.GetType(), "Ajax.Logging.Scripts.AlertListener.js")) };
}
}
}
You have to override the CreateScript and ScriptReferences property which will contain the listener specific code. The client side rule to create listener remains the same.
Enhanced Web Service Listener
In previous version the exceptions were forwarded to a static web service and the web service was called each time the publishException is called, now it supports dynamic web service url as well as method name and it also queue the exceptions in the client side and submits as batch, the default interval is 10 seconds which you can change from the LogInterval property.
Built-in Web Service
Now it has a pre-built web service which you can use to log exceptions. Just add an asmx file and add the following line:
<%@ WebService Language="c#" Class="Ajax.Logging.ExceptionLogService, Ajax.Logging" %>
And in the web service listener set the path and the method name like the following:
<AjaxLogging:WebServiceListener ServicePath="~/ExceptionLogService.asmx" ServiceMethod="Log" />
Provider Model
To record the exception in server side it uses the Asp.net Provider Model. To create a new provider you have create a class which inherits from ExceptionLogProvider and overriding the Log method.
Built-in Health Monitoring Provider
Now it comes with a Built-in Provider which uses the Asp.net health monitoring system to log the exceptions. It raises a custom event WebClientExceptionEvent to record the exception. Certainly the required settings for health monitoring needs to be present in the configuration file. The following shows a logged exception in the Event Log.

You can download the full source and a working sample from codeplex.
A small note about Asp.net Future
The upcoming release of Asp.net known as Asp.net Future also has the support to log client side exceptions. But unfortunately it does not allow to log any other exceptions except the window.onerror, also it is not as much extensible as the above, no support for listeners, not automatic logging etc. You will find the details in this link.

Filed under: Ajax