See Joel Program

February 5, 2008

JavaScript Error Publishing using ASP.NET AJAX

Filed under: AJAX, ASP.NET AJAX — Joel Rumerman @ 10:39 pm

Update: Source Code Stored Here

Let’s face it, as good of programmers that we think we are, we make mistakes. If we didn’t then all my email site would never be done for maintenance.

Now that we’ve set our egos aside, let’s talk about error handling. We’ve been handling errors on the server in a variety of ways for years. There are try/catch blocks, the generic error event at the application level, and other mechanisms for capturing and handling errors on the server. Only managing server errors was a generally accepted and okay concept as older applications used to be all about the server. However, as we continue to move more functionality to the client through JavaScript and the AJAX progamming pattern we’re shifting the balance of tasks from server-oriented to a client-oriented. By doing this we are creating more complex, dynamic applications that execute on the client,which is good for the end user, but as a result of this we have more errors occurring on the client. It just follows, the more complex code gets the more error-prone it becomes. It’s just an unfortunate fact of programming.

So while we’ve been paying attention to errors on the server for years we haven’t been paying attention to errors on the client as closely. This is something that has to change in order for us to ensure that our client code is not blowing up on user’s machines. Given that, we need a way of publishing client errors back to the server so they can be logged. To accomplish this, we’re going to create a new control that encapsulates logging client errors back to the server. It’s not a difficult concept and for this first pass (we’re going to take a second stab at this in a few weeks) we can accomplish this without too much complexity.

ErrorHandler Client Component

/// <reference name="MicrosoftAjax.js"/>
ErrorHandler = function ErrorHandler() {
    ErrorHandler.initializeBase(this);
};

ErrorHandler.prototype = {
    initialize: function ErrorHandler$initialize() {
        ErrorHandler.callBaseMethod(this, 'initialize');
        window.onerror = Function.createDelegate(this, this._unhandledError);
    },
    dispose: function ErrorHandler$dispose() {
        window.onerror = null;
        ErrorHandler.callBaseMethod(this, 'dispose');
    },

    _unhandledError: function ErrorHandler$_unhandledError(msg, url, lineNumber) {
        try
        {
            var stackTrace = StackTrace.createStackTrace(arguments.callee);
            ErrorDataService.PublishError(stackTrace, msg, url, lineNumber);
        }
        catch (e) { }
    }
}
ErrorHandler.registerClass('ErrorHandler', Sys.Component);

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

This is a pretty straight-forward client component. When it initializes it adds an event handler to the window’s onerror event. (Notice that we use direct assignment here because using the $addHandler method doesn’t work on the onerror event.)

When an error occurs our _unhandledError method executes and we have three parameters available: the error message (msg), the URL of the page where the error occurred (url), and the line number where the error occurred (lineNumber). We create another variable, stackTrace that uses our previously defined StackTrace object to create the stack trace information for the erroring call.

Once we have our stackTrace we publish our error’s information using a web service method called ErrorDataService.PublishError. We also wrap the entire method in a try/catch block because we don’t want another to get stuck in an infinite loop if we have another error occur inside our error handing code!

ErrorDataService Web Service

using System.Web.Script.Services;
using System.Web.Services;

[ScriptService]
public class ErrorDataService : WebService
{
    [WebMethod]
    public bool PublishError(string stackTrace, string message, string url, int lineNumber)
    {
        // do whatever you want at this point. Log it, create an exception, etc.
        return true;
    }
}

Once the error’s information reaches the backend its really up to you what to do with it. You could log it to the EventViewer, create a database record, or email somebody … it’s really up to you.

Now that we’ve got our web service defined that’s go back to the server portion of our ErrorHandler control.

ErrorHandler Server Control

using System.Collections.Generic;
using System.Web.UI;
using System;

namespace ErrorHandlerLibrary
{
    public class ErrorHandler : ScriptControl
    {
        protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            yield return new ScriptReference("ErrorHandlerLibrary.ErrorHandler.js", typeof(ErrorHandler).Assembly.FullName);
        }

        protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            yield return new ScriptComponentDescriptor("ErrorHandler");
        }

        protected override void OnPreRender(System.EventArgs e)
        {
            base.OnPreRender(e);
            ScriptManager.GetCurrent(this.Page).Services.Add(new ServiceReference("~/ErrorDataService.asmx"));
        }

        protected override void OnInit(System.EventArgs e)
        {
            base.OnInit(e);
            if (Page.Items.Contains(typeof(ErrorHandler)))
            {
                throw new InvalidOperationException("Only one ErrorHandler control is allowed on the page at a time.");
            }
            Page.Items.Add(typeof(ErrorHandler), this);
        }
    }
}

In the server portion of our ErrorHandler control we do five things:

  1. We inherit from ScriptControl. This wires our control up into the ASP.NET AJAX server control creation processing.
  2. We register a ScriptReference for the JS file that contains our client ErrorHandler control.
  3. We create an instance of our ErrorHandler client component using a ScriptComponentDescriptor.
  4. We do something a little special and we add a ServiceReference to our ErrorDataService. This is a little abnormal as this is normally done through markup at the page level. However, we’re going for encapsulation here, right?? So we want to encapsulate the need for a the ErrorDataService web service within the control. There is a huge caveat with this approach, though. If the control is added to the control’s collection while in a partial postback (i.e. an UpdatePanel), the ServiceReference will not be added to the page. This is extremely annoying and in my opinion a large oversight by Microsoft. I asked them about this once and their response was that they never planned on a ServiceReference being used this way… wow …
  5. We ensure that our page only ever has one ErrorHandler control on it at any given time. We do this using the same approach taken by the ScriptManager control.

Finally, we edit the AssemblyInfo.cs file to register our JavaScript file as a WebResource (not shown).

That is all we need to do to build our ErrorHandler control. Let’s build a little test page that shows it in action.

Test Page

The code below shows the important portion of our test page.

<asp:ScriptManagerID=”SM1″runat=”server”>
<
Scripts>
<
asp:ScriptReferencePath=”~/StackTrace.js” />
</
Scripts>
</
asp:ScriptManager>
<
cc1:ErrorHandlerID=”ErrorHandler1″runat=”server” />

<asp:Buttonrunat=”server”OnClientClick=”tester();”Text=”Test Client Error Handling” />

<scripttype=”text/javascript”>
function
tester() {
var test = null;
test.err = 4;
};
</script>

When we click our button we execute the tester method, which causes a null exception to occur. When this happens our ErrorHandler control jumps into action! Seeing it in action is actually hard to see because if we attach a debugger to the client it’ll break on the error and we’ll never get to our onerror handler. So, we turn to Fiddler! The picture below shows Fiddler once our error method kicks off.

image

The information in the top-right pane shows us the information we passed in to the call. The information in the bottom-right pane shows us that our method returned the value “true.”

So that’s really it. With our ErrorHandler control we can trap unhandled JavaScript errors and publish the information about them back to the server getting more insight into the errors that our users are experiencing at the browser level.

BTW: I’m looking for a place to post ZIP files for the source code as WordPress doesn’t allow .zip extensions to be uploaded. If anybody’s got a good spot, pass it along

23 Comments »

  1. […] Stack Traces in ASP.NET AJAX and JavaScript Error Publishing using ASP.NET AJAX: Joel Rumerman has put together two nice posts that detail some god ways to capture JavaScript […]

    Pingback by Feb 17th Links: ASP.NET, ASP.NET AJAX, Visual Studio, .NET - ScottGu's Blog — February 17, 2008 @ 11:19 am

  2. Great Blog, im getting into the asp.net AJAX thing and this place is great reference.
    For file storage you can try: http://www.mediafire.com/
    or else you can also publish your entry in a place like codeproject and post the source code there.
    regards

    Comment by Francisco — February 17, 2008 @ 11:49 am

  3. Thanks Francisco! I like MediaFire. Pretty nice site. I’ll see how it works and probably update this post with full source.

    Comment by Joel Rumerman — February 17, 2008 @ 2:33 pm

  4. have you thought of putting it on Code Gallery (http://code.msdn.microsoft.com/)?

    Comment by Richard — February 17, 2008 @ 9:50 pm

  5. It’s a sad day when I have to admit I’d never even heard of the Code Gallery before… and I thought I knew most everything 🙂

    It looks like an excellent choice for posting source code.

    Thanks!

    Comment by Joel Rumerman — February 17, 2008 @ 10:25 pm

  6. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials | Tutorials | Smashing Magazine — October 16, 2008 @ 1:48 pm

  7. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by Useful AJAX Tutorials | Neurosoftware web dev — October 16, 2008 @ 11:01 pm

  8. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials | POLPDESIGN — October 17, 2008 @ 11:15 pm

  9. […] JavaScript Error Publishing using ASP.NET AJAXUse AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials | Web Burning Blog — October 18, 2008 @ 12:07 am

  10. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by 50+ Great Ajax Tutorial | Tech User, Blogger and Designers References — October 21, 2008 @ 3:36 am

  11. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials | Evolution : weblog — October 30, 2008 @ 8:28 pm

  12. Hello… Great article…
    I´d like to known if is possible to let the ErrorDataService Web Service(asmx) in the Server control…
    I got a sample from Addison Wesley book and the asmx stay on the Web side…

    Thanks

    Comment by Paul — November 12, 2008 @ 12:05 pm

  13. […] JavaScript Error Publishing using ASP.NET AJAXUse AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials | How2Pc — December 19, 2008 @ 12:38 am

  14. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials « Rohit Dubal — February 16, 2009 @ 2:38 am

  15. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by Best Ajax Tutorials and Dynamic Solution for PHP ,Asp.net.Ruby On Rrails | Click On Tech — February 23, 2009 @ 6:19 am

  16. […] JavaScript Error Publishing using ASP.NET AJAX – This tutorial shows the steps in using AJAX to display errors in codes. […]

    Pingback by 150 AJAX Tutorials » TemplateLite.com — May 13, 2009 @ 5:11 pm

  17. […] JavaScript Error Publishing using ASP.NET AJAX – This tutorial shows the steps in using AJAX to display errors in codes. […]

    Pingback by Best of 158 Ajax Framework,JavaScript Libraries and Toolkit Tutorials | Click On Tech — May 14, 2009 @ 3:24 am

  18. […] JavaScript Error Publishing using ASP.NET AJAX – This tutorial shows the steps in using AJAX to display errors in codes. […]

    Pingback by Ajax Frameworks,JavaScript Libraries and Toolkit Tutorials | Dev Techie — May 14, 2009 @ 7:46 pm

  19. […] JavaScript Error Publishing using ASP.NET AJAX – This tutorial shows the steps in using AJAX to display errors in codes. […]

    Pingback by Ajax Frameworks,JavaScript Libraries and Toolkit Tutorials | Dev Techie — May 14, 2009 @ 7:46 pm

  20. Great code example thanks!

    However, there are bugs in it nothing, tweaking can’t help.

    First is a javascript error off the bat before the page is processed by the browser. You code will not work in this instances I have tried it.

    Second, isyou have bugs in the errorhandler.js file

    publishError: function ErrorHandler$handledError(error)

    Is getting in error but when trying to

    ErrorDataService.PublishError(stackTrace, msg, url, lineNumber);

    it gets an error because 3 out of the 4 variables do not exist in that method….

    Both are easily resolved.

    #1 define your own onerror method that calls the service to report inital pageload errors.

    It will get redefined by the control once it loads up.

    #2 use the information in the error object. unfortuantely the error object does not have line number or url. So I set the line to 0, and the url to document.location.href

    thanks though, thinking about buying the books 🙂

    Comment by Angela — September 6, 2009 @ 5:20 pm

  21. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by 50 Excellent AJAX Tutorials | 9Tricks.Com - Tips - Tricks - Tutorials — October 2, 2009 @ 7:57 pm

  22. […] JavaScript Error Publishing using ASP.NET AJAX Use AJAX to display errors in code. […]

    Pingback by Geek is a Lift-Style. » 50 Excellent AJAX Tutorials — June 18, 2010 @ 1:11 am

  23. […] JavaScript Error Publishing using ASP.NET AJAX […]

    Pingback by 120+ AJAX Tutorials | Pulse2 Technology and Social Media News — May 18, 2012 @ 3:20 pm


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.