Advanced JavaScript Debugging Techniques

By on April 3, 2008 1:53 pm

The purpose of this article is to provide a list of advanced debugging techniques that are not easily found elsewhere on the web. Using Google to search for JavaScript debugging just gives you hundreds of articles about using alerts and how Firebug works. We all worship at the altar of Firebug, but there are things that can go beyond a console.log(). The following is a list of methods that every developer should have in their toolbox.

Preventative Tips

Refresh Often – As most web programmers have figured out, the more edits you make to your script the greater the chance of error. The area where those errors can occur also widens exponentially. Try to keep your edits to one script block at a time and test.

Multiple Undo – If your IDE supports it, jack up your undo/history to at least 100 levels. This can be a lifesaver when your edits just seemed to break everything and your money ahead by backing them out and starting over.

Copy/Revert – Before you back out the changes of an extensive but bad edit, copy the whole script and paste it into a new file, then undo your code to the original state. You can then reintroduce the new edits a little at a time to isolate where the error occurs.

General Debugging

JSLint – Don’t be a hero. Copy and paste the script into JSLint. Not only will this do a great job of finding the cause of your error, it will also point out some bad programming habits and accidental globals (not using var) and show you all of your missing semi-colons.

Price is Right – Insert numbered log messages console.log(1), console.log(2), etc. into various areas of your code to narrow down the area with the problem. Keep adding more logs on different lines with higher and lower numbers (get it?), using 1.5, 1.73, whatever, until you key in on the line that’s the problem. This is similar to using break points, but gives you a different look.

Take Away – Comment out large chunks of code to isolate the problem. I’ve gone so far as to disable the entire app and reintroduce the code a little at a time from the beginning. Consider this a very broad Price is Right technique.

Talk About It – I can’t even say how many times this has worked: before I even finish describing the problem to a coworker… I get the “AH HA” moment.

Walk Away – Sometimes you need to walk away and clear your head. Take a break. Maybe put the code aside and sleep on the problem and revisit it the next day. This really works wonders, as it releases the tension in your brain and allows it to solve the problem in a different, more relaxed state.

Google It – While this is fairly obvious, if the problem can be described simply you can search for it. This doesn’t work so well if it’s complex, or if you have a problem like “args has no properties”. But it does work if you encounter something obscure such as “No such interface supported”.

Snapshot of Object – Although usually not the case, sometimes the object changes from the time Firebug logged it to the time you look at it. I’ve witnessed this problem in dojo.data stores. I use dojo.mixin({}, myObject) to make sure the object logged is in the right state.

IE Debugging

IE Silently Fails – Arguably, this is the biggest annoyance of IE—the page just doesn’t load and doesn’t give any errors. Sometimes you need to view the page again in Firefox. If it’s not an IE specific error, Firebug will pick it up. If Firebug loads normally, the chances are it’s one of two IE specific errors: a trailing comma, or unsupported XML syntax.

JSLint Again – JSLint will pick up code that is a problem for IE but not necessarily for Firefox.

Trailing commas – Search your script for: ,} and ,] (allowing for line breaks, tabs, and white space, etc.). This will catch the infamous “trailing comma” problem that fails silently in IE but not in Firefox.

MS Script Editor Inconsistencies – I’ve found that sometimes IE just notifies you of an error without giving you the option to debug the script. This seems to be session based—if you close the page and reopen it, it will give you the option to debug—that is, if you have its cryptic debug settings properly configured.

XML – Where to start! There are many XML differences between IE and Firefox. I believe most of IE’s XML functionality works in Firefox. So in short, whenever working in XML, make no assumptions that it will work in IE without checking.

Break Point Debugging

Step-Wise Debugging – For logic errors, there’s sometimes no substitute for peppering break points around likely-looking places, and walking through line-by-line, function by function—in Firebug/Venkman/MSE/Visual Studio—all of which support stepwise debugging.

Dojo Toolkit-specific tips for stepwise debuggingdojo/event and dojo/method blocks are very difficult to work with in the debugger. Also, if you can avoid going down the intricacies of dojo.declare (object instantiation) when you are debugging, you’ll save on valuable sanity best applied elsewhere—step out whenever you hit it. The same goes for dojo.connect—you are best off putting a break point in the function you are connecting to, rather than stepping into the connect invocation.

The Step Through – You can set watches to see expressions evaluated at each point, but you can also use the console to craft your own expressions—with the Dojo Toolkit at your disposal there, there’s not much you can’t do mid-flow to really get a picture of what’s going on. Have a file of snippets handy for pasting into the console for each project—like to check a particular property on all widgets.

Dojo Toolkit Specific Debugging

Include Dojo files – Try setting debugAtAllCosts to true in djConfig. This didn’t work for a little while during the Dojo 0.9 period, but it’s working quite well now with the exception of a few fringe cases. The dojo.loader uses XHR to load script files and initializes them with eval. This unfortunately confuses the debuggers and thinks all errors occur within the dojo.loader. debugAtAllCosts tells the dojo.loader to attach all the scripts traditionally in the head of your document, where debuggers will have an easier time pinpointing the problem area.

Syntax Catcher ‘Beta’ – I’ve submitted code to the Dojo Toolkit that detects if a file has an error on load, such as a typo, missing bracket, etc. This is enormously helpful, especially if you’re a fast, sloppy typist; it saves you the trouble of reloading with debugAtAllCosts or visiting JSLint just to find an incorrect character. Unfortunately, there are still a few problems getting it to work with IE. But you can use it in your personal copy of the Dojo Toolkit by grabbing the latest syntax catcher code.

Firebug Tips

Firebug Documentation – Make sure to read both the command line API and console API in Firebug’s docs. They allow you to do some pretty crazy things beyond just logging.

Command Line

Real Time Editing – Editing code in real time sure beats waiting for things to go to staging. Basically, use whatever console is available (and at this point, you can do this in any browser—see the tools below) and replace the function with modified code. This would look something like: foo.prototype.bar = function(){}. It also allows you to work on code without having to refresh the page. If you’re working with the Dojo Toolkit, you can even use dojo.require to load a file or a package and work with it right there.

Expressions Testing – Use the console command line to directly test your expressions. This example pulls names out of email contacts:

'"Mike Wilcox" , "Tom Trenka" '
.match(/(['"])([^'"]*)\1/g)

Open the console in Firebug and paste in that example and click ‘Run’. This works great with the date object too, and testing its myriad methods.

Debugging Tools

Firebug LiteFirebug Lite works in IE and other browsers, and if you’re using the Dojo Toolkit it comes included, with some enhancements like launching in a separate window, and an object inspector. And of course there’s Firebug itself, but you knew that.

Debug Bar – Debug Bar Core Services has released Debug Bar, a Firebug equivalant for IE. Great inspectors for the DOM, HTTP, script and style sheets. Plus it provides you with much needed IE error handling. It has a JS command line, but in spite of its claims, it seems to be lacking any actual logging.

Fiddler Fiddler is a very robust proxy that logs your HTTP calls. More information than you’ll ever need. Claims to work all browsers, but it uses the .NET Framework, so it’s Windows only.

HTTP Live HeadersHTTP Live Headers works on a Mac, and captures all of your HTTP calls.

Web Development Helper – Another Firebug equivalent for IE, Web Development Helper is a pretty nice little app, with many of the same features as Debug Bar, except that it’s free, and it actually has a logging feature, although it’s plain text. A lot of the information appears in pop-up windows, which hurts persistence. It has an object inspector, but that too is in a window. However, this is definitely worth a look.

Internet Explorer Developer Toolbar – Microsoft’s Internet Explorer Developer Toolbar is certainly an improvement over what it had before. A lot of inspectors and shortcuts to useful features like cache clearing (which now takes two clicks instead four).

Debugging Links

The Dojo Book – Debugging JavaScript

An In-depth Look At The Future of Javascript Debugging With Firebug

HOW-TO: Debug JavaScript in Internet Explorer

IE Blog – AJAX Experience & Tools

This list of debugging techniques came about as a collaborative effort from other members of the SitePen team besides myself. Contributors to this list include: Kris Zyp, Neil Roberts, Sam Foster, Joe Walker, Tom Trenka, and Dylan Schiemann.

Are there some good tricks that have been left out of this list? Continue the collaborative effort and post them in the comments.

Comments

  • I definitely recommend JSLint, but ideally automating the JSLint checks before a build. The most frequent issue I have is those darn trailing commas that screw up IE, but thankfully the automated JSLint check flags them before I can commit any release build, as I only commit release builds via a script.

    Here’s the script I use for calling JSLint. In my build, this is the first check before scripts for running the dojo build system, modifying my html for release, etc. Hope it’s useful to someone.

    Oh, and “constants.bash” here just defines $DOJO_VERSION.

    -Adam Fisk
    http://www.littleshoot.org

    #!/usr/bin/env bash
    function die()
    {
    echo $*
    exit 1
    }

    source constants.bash
    rhinoJar=../server/static/build/src/main/webapp/$DOJO_VERSION/util/shrinksafe/custom_rhino.jar
    jsDir=../server/static/build/src/main/webapp/littleshoot

    function badJs()
    {
    echo “Printing errors”
    java -jar $rhinoJar jslint.js $1
    exit 1
    }

    function checkFile()
    {
    java -jar $rhinoJar jslint.js $1 | grep “No problems found in” || badJs $1
    }

    for i in $( ls $jsDir/*.js ); do
    echo “Checking JavaScript file: $i”
    echo $i | grep “AC_QuickTime” || checkFile $i
    done

    echo “Completed all checks successfully.”
    exit 0

  • I use a version of Firebug that supports debugging eval’d code, which is endlessly helpful when you have a lot of dijits.

    http://dojotoolkit.org/pipermail/dojo-contributors/2007-April/007007.html

  • For stuff that’s applicable, unittesting (JSUnit) is a great way not to have to debug.

  • Charles is a more powerful version of Fiddler, but it’s also available for OSX and Linux.

    http://www.xk72.com/charles/

  • @Julien: agreed… there’s also the Dojo Objective Harness (DOH), which helps unit test JS code both in the browser and from the command line.

    @Rob: You’re right, and we use Charles all the time. Not sure how that slipped our minds!

  • Hi, Mike.

    I’ve developed a cross browser debugging tool that contains some Firebug features.

    You can try it in here: http://kodfabrik.com/app/pi.debugger

    And get more detailed information at pi project’s website: http://pi-js.googlecode.com

    Azer

  • Tom

    @Rob Coup,
    Charles looks great! thanks for the tip.
    Gonna try it out the next 30 days

  • > Talk About It

    There’s a great anecdote from Chris Sells about this that I’ve used numerous times:
    http://www.sellsbrothers.com/spout/archive.htm#teddybear

    > Trailing commas
    IIRC, this is picked up by JavaScriptLint (a different tool from JSLint, and IMHO better as it’s built on SpiderMonkey)

    Also, you should look into enabling javascript.options.strict in Firefox:
    http://dean.edwards.name/weblog/2007/08/firebug-slow/

  • Also, don’t forget to tweak your Apache settings so that javascript files are not cached. This htaccess snippet will give files ending in .js a maximum age of ten seconds:

    Header set Cache-Control “max-age=10”

    It can be really annoying to have to clear your cache every time you make a change.

  • Thanks for summarizing all this, great!
    Just my 2 cents

    JSLint – use Komodo or some IDE that has JSLint checks on the fly, since that I never had any trailing comma again, great IDE!

    Price is Right – or use the statement “debugger;” to set a breakpoint in your code (of course therefore the js sources must not be loaded via AJAX and evaled, use debugAtAllCosts)

    Talk About It – this is so true!!!!! :-)

    Refresh Often – I realize that this makes me slow (though i do it quite often :-) ), switching between apps and may be having my code run in a none-built version loads the site pretty slow.
    I suggest try what you want to do in FireBug first and then go into your code and hack it, If you are experienced you can hack quite a bit without going back too often to reload. But I agree, test test test is surely the best :-)

    thx!

    Wolfram

  • It might be a *slight* tangent, but I’d also recommend using this sort of code to keep track of when other people experience errors.

    window.onerror = function( err ){
    ajaxcode.sendError( err, loggingCode.lastItems );
    };

    In the past I’ve kept a log of users path through the code (e.g. last 50 points of interest) so that you’ve then got a clue as to the context in which an error happened. It’s a bit clunky though so use your discretion.

  • Great comments so far!

    @Richard: Not off topic!

    I think the reason I’m so fascinatd by debugging and logging is because I’m looking for transparency in my code. I want my code to talk to me, outside of it’s intended application. I want it to say “this equals this, there are this many items, and there is a mistake, and this mistake is right __here__”. That’s why I glossed over the break point sections. And that’s why your suggestion isn’t off topic, as it furthers that transparency. It’s also a solution Dustin addressed in his blog about Dojox Analytics on
    03/13/2008.

  • While going through my notes on this subject, I came across one that definitely should not have been omitted:

    IE Silently Fails on Reserved Words

    This is something that JSLint-type progs will pick up. But it’s still something that can mess up even seasoned programmers. I myself have mistakenly used “class” more than once, and sometimes the code will lead you down a path that lulls you into forgeting to watch for this. We had a hash map of translated words, and a bunch of us tripped over translated button titles like “import” and “export”.

    I should note Firefox gets part of the blame for __allowing__ reserved words.

    Just Google: JavaScript reserved words.

  • Sushant Srivastava

    I use gvim to edit my javascript files.
    jsl is a nice utility
    and here’s a neat way to integrate it with vim.

    Also, working with IE is a real pain.Wish somebody develops a firebug clone.

  • A friend of mine built an interactive javascript shell, which (sort of like the python interpreter) allows you to check a lot of things in isolation, but with all browser objects available. Pretty cool stuff, and occasionally very nice for debugging:

    http://johnnydebris.net/projects/jsshell/jsshell.html

  • Excellent post! I’ve bookmarked it and will certainly return to it when I am frustrated and banging my head against the wall over a JavaScript bug. Having a list of debugging techniques on hand is great for when you’re stuck.

    Things that have served me well thus far are developing for Firefox first and foremost and patching for IE as necessary, and making extensive use of Firefox’s Firebug JavaScript console and debugger. Being able to set conditional breakpoints, log messages and check the state of the DOM at any point during execution is invaluable. I just wish there was something as full-featured for IE! In all fairness, there is a small offering by way of the Script Editor (and the even-worse Script Debugger). But, it doesn’t feature a fraction of the functionality or user-friendliness of Firebug.

    As for shotgun debugging, one thing that my friend Lowell pointed out is that commenting out large blocks of code is easy if you use two slashes for your code (//). It’s more difficult if you use /* */ since each time you do that, you’ll need to add another opening comment. For this reason, he always uses two slashes for comments and uses the other style of multi-line commenting exclusively for commenting out code.

    One other point in this discussion: Depending on the JavaScript library or framework in use, exceptions will sometimes be swallowed and the application will silently fail. This has happened to me quite a bit when using Prototype/Scriptaculous as well as at times with jQuery. Interestingly enough, MooTools seems to be really good at raising exceptions. Is there a philosophy behind this? For example, don’t raise the exceptions for users as it will cause an annoying error popup in Internet Explorer?

    It seems that libraries would benefit from having a “development mode” flag that you set when you are coding the site, and turn off when deploying to the live production server. When the flag is on, exceptions would be raised, but you could disable it before deployment and errors would cause silent failure.

    One final thought– do you do much error handling outside of checking an Ajax response from the server? I can’t think of many times where I would try() catch() something. Instead, if there is the possibility something would be undefined, I check if (typeof obj == “undefined”). It’s been working pretty well for me so far but I’m wondering what some cases would be that I might use error handling.

    -Jonah Dempcy
    http://www.thetruetribe.com

  • @Jonah: something I tend to use instead of /* */ is if(0){} blocks… works as well as comments, and they can be nested.

    in Dojo, we do have a flag for debugging being on or off, though we use this mostly for whether console.log and console.debug statements are executed with Firebug or Firebug Lite rather than a way of suppressing all exceptions.

  • @Dylan: Thanks for the tip! I’ll start doing this, and now I can use multi-line comments again.

    I’ll look into Dojo’s debug mode. I wrote an article about rewriting console.log statements with a debug mode flag:

    http://www.thetruetribe.com/2008/04/redefining-consolelog-for-browsers.html

  • Mariam

    hi iam mariam i want to make a calculator by form function in javascript from wich code ican add sin , log pleas tell me

  • If you are on MS Windows and need to debug javascript in Internet Explorer you should give a try to VWD (Visual Web Developer Express Edition).

    It has HTML, JS, CSS,XML,… editing helpers.
    A very powerful javascript debugger.
    An integrated web server, and… it is FREE!

    I used it happily for years.
    One sad thing, the XSLT debugging is not available in the free version.

    As I moved to a Mac now, I switched to an Emacs-Firefox+Firebug environment.

  • sathya

    Break Point Debugging >> Step-Wise Debugging is not working in Venkman for me even after making isDebug & debugAtAllCosts true. Am I missing anything?

    I am able to set break point, but control is not coming there.

    Please advise.

  • Recently I thought of a cool trick. When you have a lot of vars to log, stick them in an object, and log it with dir():

    console.dir({
    b:b,
    bc:bc,
    tableSelector:tableSelector,
    tableStyle:tableStyle,
    pad:this.getPadding(),
    space:this.getSpace(),
    width:this.getWidth()
    });

  • ayound

    JSDT(Javascript Debug Toolkit) is a eclipse plugin used to debug javascript cross browser, jsdt can used in IE ,FIREFOX ,SAFARI,CHROME browsers and so on.

    http://code.google.com/p/jsdt/wiki/newFeatures

  • We are using Charles, Fiddler and Firebug. They all great, and more than enough for our needs.

    F.