The Code Page
A series of development tips and code examples by Gabriel McAdams
Feb 02

Over the years, I have encountered a few web developers who ignore client side (JavaScript) errors in their applications.  Some have even asked me for ways to suppress client-side errors all together.  With the growing amount of client-side code in web applications, this is a big concern.

It may seem to some that JavaScript errors are inconsequential, but this is not the case.  They are errors just like any other.  Whenever an error occurs, your application is no longer doing what you designed it to do.  A lot of developers feel that there is nothing they can do.  That is on the client.  I have no way of knowing what happens on the client.  In this post, I will provide code that allows the developer to receive notifications whenever a JavaScript error occurs on the client.

This code is a server control designed to allow .Net developers to log JavaScript errors on the server the same way they can log server-side errors.  The control has a very small footprint.  It’s simple to use.  And it takes up no visible space on the page.

The control uses window.onerror to capture JavaScript errors and send the error information to the server using the iCallbackEventHandler interface (note: As of this writing, window.onerror doesn’t work in Google Chrome).  Whenever a JavaScript error occurs, the control raises an event on the server that can be handled in the page.

To use the control is very easy.  Simply add this to your markup:

<cc1:JSErrorNotifier ID="JSErrorNotifier1" runat="server"
    OnJavaScriptError="JSErrorNotifier_JavaScriptError">
</cc1:JSErrorNotifier>

and this to your code-file:

protected void JSErrorNotifier_JavaScriptError(object sender, WebControls.JavaScriptErrorEventArgs e)
{
    e.DisplayMessage = "A JavaScript error has been received by the page";
}

 

Download Source Code: JSErrorNotifier.zip


Comments

Toi said:    

That's a wonderful tip. Smile

Comment Posted: February 10 2010, 09:19 AM

therapon said:    

I did the same but my solution is ajax/vbnet. When I press the button is not entering in the event JSErrorNotifier1_JavaScriptError. Could be a problem on my setup of the webcontrol?  

Comment Posted: February 12 2010, 03:26 PM

ghmcadams said:    

@therapon: What browser are you using?  I ask because Chrome is not supported yet.  Beyond that, maybe you could show me your code so I can take a look.

Comment Posted: February 13 2010, 01:57 AM

therapon said:    

of course gabriel ... it is a test environment (IE8):
<%@ Page Title="" Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<%@ Register Assembly="WebControls" Namespace="WebControls" TagPrefix="cc1" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <input id="Button1" type="button" runat ="server"  value="button" onclick="error_t()"/>
        <cc1:JSErrorNotifier ID="JSErrorNotifier1" runat="server" OnJavaScriptError="JSErrorNotifier1_JavaScriptError">
        </cc1:JSErrorNotifier>
    </ContentTemplate>
    </asp:UpdatePanel>
</asp:Content>

Partial Class _Default
    Inherits System.Web.UI.Page

    Protected Sub JSErrorNotifier1_JavaScriptError(ByVal sender As Object, ByVal e As WebControls.JavaScriptErrorEventArgs) Handles JSErrorNotifier1.JavaScriptError
'breakpoint      
dim x =0
    End Sub
End Class

Comment Posted: February 13 2010, 09:12 PM

ghmcadams said:    

@therapon: I ran the code you posted, and it worked fine for me.  I noticed that you placed it in an update panel.  Perhaps if you moved it out directly into the form.  Also, consider placing in your master page, so that all pages benefit.

Comment Posted: February 13 2010, 09:25 PM

therapon said:    

thank you for your answers gabriel. Anyway, so strange... as you suggested I tried to put it in the masterpage ContentPlaceHolder
but still no entering in the breakpoint at the event JSErrorNotifier1_JavaScriptError (now in the master). I ran the code you posted, and it worked fine for me  have you tried to put a breakpoint with VS2008?

Comment Posted: February 14 2010, 09:24 AM

ghmcadams said:    

Yeah.  My breakpoint hit.  Do me a favor - Go to the contact page and send me your project (zipped).  I will run it here and see what I can find.

Comment Posted: February 14 2010, 09:59 AM

therapon said:    

gabriel you're great, i tried to run this website directly on iis and it's working properly but I cannot catch the javascript error on vs2008 yet. ok no problem thanks again

Comment Posted: February 14 2010, 08:34 PM

ghmcadams said:    

If that's the case, then maybe it is getting to your code, but you don't have your project setup for debugging.  Go to this page for information on setting up your project for debugging:  msdn.microsoft.com/en-us/library/e8z01xdh.aspx

Comment Posted: February 14 2010, 08:46 PM

therapon said:    

mah...on my web.config <compilation debug="true" strict="false" explicit="true">. The problem is the project stops in debugging for client-side (javascript Microsoft JScript runtime error: Object expected) but after (break/continue/ignore) is not entering in vb server-side. Running the project without debugging it's doing the right thing. Maybe shall I change the "exceptions" in the vs-debug menu to not stop debugging on javascript errors?

Comment Posted: February 15 2010, 09:43 AM

ghmcadams said:    

This just occurred to me.  You debug differently than I do.  When I press F5 (start debugging) I have the same problem you do.  You see, when you do that, you're debugging both the client (IE) and the server.  Debugging the client must have an effect on window.onerror

It will work if you do this (to only debug the server):

Instead of hitting F5 (or the play button), right click the page and click "View in browser"

Then click Debug > Attach to Process

Choose the process that looks like this:

"ASP.NET Development Server - Port XXXX"

Now it should hit your breakpoint.

Comment Posted: February 15 2010, 07:58 PM

therapon said:    

One question or improvement: Is it possible to get the source code of the relative error line(s) of the page as seen from the client ("document.documentElement.innerHTML")? Or at least the browser used by the client...  

Comment Posted: February 15 2010, 11:00 PM

ghmcadams said:    

Unfortunately, there is no way that I know of to get that text.  There is no API to read the html or external script files by line number.  You would have to load the file manually and go to that line (and what if you're reading a dynamic page?  You would first have to generate the page and parse it.

Comment Posted: February 16 2010, 04:02 AM

juarola said:    

I tried to squint my eyes, but i still cannot see where the code is Smile Has it been removed at some point?

Comment Posted: October 17 2010, 08:50 PM

Michael freidgeim said:    

What are the benefits of your control compare to james.newtonking.com/.../...Errors-To-ASP.NET.aspx

Comment Posted: November 17 2011, 10:16 AM

ghmcadams said:    

@Michael freidgeim: James has written a good logger.  His value seems to be that it doesn't create the page on the server, and that provides some (although usually very minor) performance gains.  The cost, though, is with it's complexity.  When you use his logger, you have to register the HttpHandler in the web.config and then its up to you how you get to the error on the server.  You have to add more lines to your web.config, and if you want to do something special with the error, then you have to write a custom provider first.

My control is very simple to use.  You just add the control to your page (or master page), and add an event handler in your code file.  It even gives you the ability to provide a message to the user that is generated on the server (with a default).

My control also considers that somewhere in the page, window.onerror may have already been set.  If that's the case, it still gets called, just before my control.

Comment Posted: November 20 2011, 02:11 AM

Keith Powers said:    

Great simplicity for the Developer to use.
User Broswer Info can be captured from the Request object but is not always reliable. (See the JSErrorNotifier_JavaScriptError method implementation, below).  

The only problem i see with using this as the Java Script error info provides inadequate detail; if the line number does not correlate to the source code - which it may not in a large rendered page - it is of very limited use.

protected void JSErrorNotifier_JavaScriptError(object sender, WebControls.JavaScriptErrorEventArgs e)
  {
        StringBuilder sb = new StringBuilder(1024);
        sb.Append(e.Message);
        sb.Append(Environment.NewLine);
        
        sb.Append("Client Line Number: ");
        sb.Append(e.Line.ToString());
        sb.Append(Environment.NewLine);
        
        sb.Append("URL:");
        sb.Append(e.Url);
        sb.Append(Environment.NewLine);

        sb.Append("ClientIP: ");
        sb.Append(Request.UserHostAddress.ToString());
        sb.Append(Environment.NewLine);

        sb.Append("<BrowserInfo>");
        sb.Append("<Type>");
        sb.Append(Request.Browser.Type);
        sb.Append("</Type>");

        sb.Append("<BrowserName>");
        sb.Append(Request.Browser.Browser);
        sb.Append("</BrowserName>");

        sb.Append("<MajorVersion>");
        sb.Append(Request.Browser.MajorVersion.ToString());
        sb.Append("</MajorVersion>");

        sb.Append("<MinorVersion>");
        sb.Append(Request.Browser.MinorVersionString);
        sb.Append("</MinorVersion>");

        sb.Append("<Platform>");
        sb.Append(Request.Browser.Platform);
        sb.Append("</Platform>");

        sb.Append("<IsBeta>");
        sb.Append(Request.Browser.Beta.ToString());
        sb.Append("</IsBeta>");

        sb.Append("<IsCrawler>");
        sb.Append(Request.Browser.Crawler.ToString());
        sb.Append("</IsCrawler>");

        sb.Append("<IsAOL>");
        sb.Append(Request.Browser.AOL.ToString());
        sb.Append("</IsAOL>");

        sb.Append("<IsWin16>");
        sb.Append(Request.Browser.Win16.ToString());
        sb.Append("</IsWin16>");

        sb.Append("<IsWin32>");
        sb.Append(Request.Browser.Win32.ToString());
        sb.Append("</IsWin32>");

        sb.Append("<SupportsFrames>");
        sb.Append(Request.Browser.Frames.ToString());
        sb.Append("</SupportsFrames>");

        sb.Append("<SupportsTables>");
        sb.Append(Request.Browser.Tables.ToString());
        sb.Append("</SupportsTables>");

        sb.Append("<SupportsCookies>");
        sb.Append(Request.Browser.Cookies.ToString());
        sb.Append("</SupportsCookies>");

        sb.Append("<SupportsVBScript>");
        sb.Append(Request.Browser.VBScript.ToString());
        sb.Append("</SupportsVBScript>");

        sb.Append("<SupportsJavaApplets>");
        sb.Append(Request.Browser.JavaApplets.ToString());
        sb.Append("</SupportsJavaApplets>");

        sb.Append("<SupportsActiveXControls>");
        sb.Append(Request.Browser.ActiveXControls);
        sb.Append("</SupportsActiveXControls>");

        sb.Append("<CDF>");
        sb.Append(Request.Browser.CDF.ToString());
        sb.Append("</CDF>");
        sb.Append("</BrowserInfo>");
    
        e.DisplayMessage = sb.ToString();
    //e.DisplayMessage = "A JavaScript error has been received by the page";
  }  

Comment Posted: December 13 2011, 10:43 PM

john said:    

thanks for this

Comment Posted: January 15 2012, 04:28 PM

michael Freidgeim said:    

Hi Gabriel,
I've wrote a post geekswithblogs.net/.../...rrors-to-the-server.aspx about renaming namespace in your DLL. Let me know if you want me to send modified code to you. Alternatively you can publish your solution somewhere (e.g. on codeplex or github) and other people can improve/extend it.

Comment Posted: April 25 2012, 04:14 AM

base10.net.br said:    

Pingback from base10.net.br

Macroblog Base10   » Log JavaScript errors to the server.

Comment Posted: August 02 2012, 08:14 PM
Add comment








biuquote
  • Comment
  • Preview


Loading



.