AJAX, PHP and Javascript Errors - How to get more data

January 1, 2006

Javascript is a powerful tool in the web programmers toolbox however, it's also one of our greatest headaches. Dealing with browser inconsistencies is always a source of great pain. You test on multiple platforms, find everyone you know with a mac running safari and think you have your code locked down however it rarely always works out this way. Being able to detect javascript errors in the wild can be a great resource for you to really see how your code is performing on a day to day basis. Mozilla and IE support a powerful event handler called "onerror" used like window.onerror = function(){};

You can create a custom function at the top of all your scripts that will record any parsing or exception errors generated. You can create your function to accept 3 parameters, the message of the error, the URL of the error and the Line number of the error. Creating this function is as simple as so:

  1.  
  2. <SCRIPT>
  3. window.onerror = function(msg, err_url, line) {
  4. alert('an error occured on line: ' + line);
  5. }
  6. </SCRIPT>


Now the end user really doesn't care which line an error occurred on but the powerful part is being able to get this information back to the developers. Using AJAX technologies you can easily record a log of all js errors on your site so you can take appropriate action to fix these issues. Not only can you include msg, line and error URL, but you can also send any other information javascript can capture such as referring page and the type of browser the client is using.

I'm going to use my standard AJAX class I use in my applications. I'm not a big fan of overhyped, oversized, slow AJAX frameworks that take a very simple concept and turn it into a serialized mess so I just use my trusty 97 line js class which can be found here http://www.litfuel.net/tutorials/js_errors/class_xmlhttp.js. I'm not going to go over ajax as I'm sure there are many other places you can get the basics. Basically this script just allows you to create an XMLHTTP object and pass POST parameters and a callback function.

To use the object you simple write:
  1.  
  2. // post data you want to send to the server
  3. var POSTData = 'msg=' + msg ;
  4.  
  5. // create the actual xmlhttprequest object and pass the URL of the PHP page you want to call
  6. var s = new XMLHTTP("error_server.php?");
  7.  
  8. // post data to the server and assign processReqChange as the function to call back when the data is posted
  9. var xmlDoc = s.call(POSTData, processReqChange);


Putting these two things together you can now log all of your JS error msgs behind the scenes and create an offline viewer that you and your other programmers can sift through. I prefer to err on the side of performance so the goal is just to log some quick info to the server and set up a cron job to email that data each night to the developers.



FILE 1 - Our main HTML File index.html
  1.  
  2. <HTML>
  3. <HEAD>
  4. <TITLE></TITLE>
  5. <SCRIPT SRC="class_xmlhttp.js" type="text/javascript"></SCRIPT>
  6. <SCRIPT SRC="js_error_logger.js" type="text/javascript"></SCRIPT>
  7. <SCRIPT>
  8. // This function does not exist so it will generate an exception error
  9. test();
  10. </SCRIPT>
  11. </HEAD>
  12. <BODY>
  13. </BODY>
  14. </HTML>


So what we're doing here is first including our XMLHTTPRequest class to instantiate our JS Object, then including the onerror functionality that will log the data to our server on every webpage. You can find the js_error_logger.js file here: http://www.litfuel.net/tutorials/js_errors/js_error_logger.js

js_error_logger.js file:
  1.  
  2. window.onerror = function(msg, err_url, line) {
  3. // create the post data string
  4. var POSTData = 'msg=' + msg + '&err_url=' + err_url + '&line=' + line + '&browser=' + navigator.userAgent;
  5. var s = new XMLHTTP("error_server.php?");
  6. var xmlDoc = s.call(POSTData, processReqChange);
  7. }


So lets step through this to find out whats going on:
  1.  
  2. window.onerror = function(msg, err_url, line) {


we're saying that for the window object, when there is an error call this function and pass in an error message, the URL and line number it occured on.

  1.  
  2. var POSTData = 'msg=' + msg + '&err_url=' + err_url + '&line=' + line + '&browser=' + navigator.userAgent;


Now we're creating some data we're POST'ing to the PHP server script. We're also including the Browser that the user is using as well.

  1.  
  2. var s = new XMLHTTP("error_server.php?");
  3. var xmlDoc = s.call(POSTData, processReqChange);


now we instatiate our xmlhttp object and call it with our POST data and assigning the call back function. I'm not going to use the callback function as this time because I want it to appear to be behind the scenes but you could also alert the user that the error was logged.

The PHP script is as simple as pie:

  1.  
  2. <?php
  3. // SERIALIZE THE POST DATA TO A FILE TO BE READ LATER ON
  4. file_put_contents('js_errors.txt', serialize($_POST)."|", FILE_APPEND);
  5. ?>


We're just serializing the POST data and appending it to our js_errors.txt file. This is the fastest and simplest way to log the data without affecting user performance. The errors file can be parsed offline without affecting server performance too much.

To create a viewer for this file you can do this:
  1.  
  2. <?php
  3. $js_file = explode('|', file_get_contents('js_errors.txt'));
  4. foreach($js_file as $errors)
  5. {
  6. $js_errors = unserialize($errors);
  7. echo '<HR>JS ERROR:<BR>';
  8. echo "MSG: {$js_errors['msg']}<BR>";
  9. echo "LINE: {$js_errors['line']}<BR>";
  10. echo "URL: {$js_errors['err_url']}<BR>";
  11. echo "BROWSER: {$js_errors['browser']}<BR>";
  12. }
  13. ?>


And what prints out is:
JS ERROR:
MSG: Object expected
LINE: 16
URL: http://localhost/misc/js_error_ajax/index.htm
BROWSER: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 3.1)

You can easily modify this as a cron job that emails this data to the developers each day.

Anyway, thats it. A simple example of using AJAX to make javascript debugging on remote systems easier. Enjoy

Comments

RSS feed for comments on this post.

  1. Dennis Pallett says:
    January 1, 2006 @ 14:27 — Reply

    Man, that's a nice way of catching errors. I'm definitely going to add that to my scripts.

  2. Jesper Rønn-Jensen says:
    January 2, 2006 @ 15:53 — Reply

    Nice article. Thanks for sharing your thoughts. However, in general, Internet Explorer has very vague error messages. Most of the time it's reporting "Object expected" (as opposed to which object expected). I often find IE to report an that an error occured in the html file when the error in reality occured in the JS file. All in all, I still think your idea is good and can be used in practice. Hopefully future versions of IE will produce more accurate error messages.

  3. Anonymous says:
    February 23, 2006 @ 00:37 — Reply

  4. C A Lane says:
    April 23, 2006 @ 21:16 — Reply

    Not working for me, I don't get js_errors.txt written to and no alert('debug data sent and logged'); , txt file is set to 777

  5. Milandi says:
    May 19, 2006 @ 19:31 — Reply

    http://www.milandi.de, deine coole community

  6. kodukas says:
    June 14, 2006 @ 12:24 — Reply

    cool

  7. Aman says:
    July 3, 2006 @ 05:41 — Reply

    This was a good article. I will surely use it in my scripts.

  8. angelsoft says:
    October 20, 2006 @ 09:55 — Reply

    great! i'll be putting it here -> www.angelsoft.ph

  9. Dan Novik says:
    January 17, 2007 @ 07:56 — Reply

    See for example JavaScript log here: http://www.servletsuite.com/servlets/jslog.htm

  10. innoceant says:
    January 19, 2007 @ 00:36 — Reply

    Well ... well Levyo Ajax Gallery has support IE 6.x & 7.x, Firefox 2.x, Netscape 8.x, not only just Microsoft products (IE). Cool.. yup . .. but the price is still rather "hight". Hix ... guys, do you know another Gallery built on Ajax like them. I see some but not cool if compare with them. 100% actions of their gallery are built on ajax www.levyo.com http://www.talkaboutcomics.com/phpBB2/profile.php?mode=activate&u=15839&act_key=185e73

  11. Kyle Klain says:
    February 23, 2007 @ 10:33 — Reply

    Exposure to your Ajax class was the most helpful thing about this - thank you for posting it.

  12. Listen to Music says:
    June 7, 2007 @ 07:39 — Reply

    Nice script Jim!

  13. Louis Vuitton Handbags Replica says:
    January 29, 2010 @ 19:25 — Reply

    Comment pending moderation

  14. RegCure says:
    April 7, 2010 @ 10:05 — Reply

    Comment pending moderation

  15. NAT says:
    April 9, 2010 @ 02:45 — Reply

    Comment pending moderation

  16. blu ray ripper says:
    April 18, 2010 @ 04:10 — Reply

    Comment pending moderation

  17. convert hd video says:
    May 5, 2010 @ 02:48 — Reply

    Comment pending moderation

  18. contact us says:
    May 29, 2010 @ 01:09 — Reply

    Comment pending moderation

  19. virbram five fingers says:
    June 4, 2010 @ 20:30 — Reply

    Comment pending moderation

  20. Replica Jewelry says:
    June 21, 2010 @ 01:41 — Reply

    Comment pending moderation

  21. air max says:
    June 24, 2010 @ 02:24 — Reply

    Comment pending moderation

Leave a Comment

Line and paragraph breaks automatic, HTML allowed: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <code> <em> <i> <strike> <strong>

Comments disabled due to spammers being losers that lead sad lives.