Production JavaScript Debugging

By Nicholas C. ZakasJune 27th, 2008

You know the scenario. A bug is filed for a JavaScript issue
in production. You update your development server to the same files (allegedly)
that are in production but you can’t reproduce the issue. Debugging your
JavaScript code is horrifically difficult, if not impossible, because you’re
following best practices and crunching the file using the YUI Compressor.

You start by typing the URL of the JavaScript into a browser to confirm that the file is there. It is, and in fact, is being loaded into the browser without issue. So something must have gone wrong during the deployment process, but you need to know what part of the code is failing. Firebug, your trusty companion for JavaScript debugging, is essentially useless as it has a hard time deciphering all of your code from a single line.

When I end up in this situation, I turn to a little-known but incredibly powerful tool from Microsoft called Fiddler. Fiddler is an HTTP debugging proxy that filters all the requests coming to your machine via HTTP. It interfaces directly with WinINET, the Microsoft Internet communications stack, so it automatically picks up any requests and responses by programs using this library. By simply starting Fiddler, it will automatically pick up HTTP traffic for Internet Explorer, Safari, and Opera. Firefox doesn’t use WinINET, so you need to manually set it up to go through Fiddler. You can do so by going to the Tools menu and clicking on Options. Go to the Network tab and click the Settings button. Select Manual Proxy Configuration and enter localhost as your server and 8888 as your port. Click OK to apply the settings.

Setting up Firefox's options in preparation for using Fiddler.

Once that’s done, you’re ready to start debugging that production JavaScript. The key to debugging is really to create a readable version of the JavaScript so that Firebug (or any other JavaScript debugger) can be used to step through the code and set breakpoints as normal. To do so, download the file in production to your local machine. Use a pretty printing tool, such as Einars "elfz" Lielmanis’ online beautifier to create a more readable version of your code and save it to a local file. It’s important to follow this process instead of using your development version of the JavaScript to ensure that you’re using the exact same code that is on production; you can more easily rule out deployment issues this way.

The Fiddler Autoresponder tab.

Next, click on Fiddler’s AutoResponder tab. The settings on this tab allow you to intercept requests and respond as if you were the server. It’s possible to respond with a status code or with actual content. To enable this feature, check the Enable automatic responses checkbox. The Permit passthrough for unmatched requests checkbox should be checked by default, which is necessary to avoid interfering with other requests. Click the Add button to create a new entry. The textbox on the left should contain either the complete URI for the JavaScript file you want to intercept, or you can create a regular expression by preceding your text with "regex". The second textbox is for the response that should be sent. Click the dropdown arrow and select Find a file. Select the pretty-printed JavaScript file from your computer and click the Save button. This places your filter in Fiddler’s memory so the next time a file matching the given URI or description is requested, it will respond by sending back the file on your computer.

After that, you can navigate back to the production server on which the problem exists knowing that your file will be inserted in place of the actual production file. The browser itself is none the wiser that the file has been swapped out, so you’re safely able to debug readable code without making any changes to the code on the server. This technique has helped me debug some of the more complex issues I’ve dealt with at Yahoo!, and I hope that it can help you as well.

13 Comments

  1. Neat trick. I knew of Fiddler, but didn’t know it could intercept requests and furnish its own custom responses.

    Now the inevitable question: know of any tools to do a similar thing on Mac OS X?

  2. For debugging a weird JS issue, I just copy the error line in Firebug – then go to Information > View Scripts in Firefox’s Web Developer Tool bar plugin, find the location of the offending JS file by doing a search for that line. Then I can run the js file in the beautifier link (above) if needed.

    If you need to make modifications on a live site but don’t have access to it you can also just add entries in your etc/host file (on both Mac and PC) for easy request redirection. For example I can add an entry for static.yahoo.com to point to my own ip, then download their js files to a folder on my localhost and modify them their to debug/see what my changes would look like in the live production system. Works like a charm and on any browser.

    Tamper Data plugin for Firefox is also good for tampering with GET/POST requests and you can modify a great deal of information.

  3. @Brad – I haven’t yet come across a tool similar to Fiddler on Mac OS X. Though, I’d be surprised if there isn’t something out there that is similar.

    @Mauvis – I’ve used those techniques as well, thanks for mentioning the etc/hosts file. That’s a great solution, especially for Macs where you can run Fiddler. I’d also echo that Tamper Data is useful for Firefox, but since it only is available for Firefox, leaves a large portion of the A-grade browsers to still investigate in another way. That’s why I like Fiddler: I can do it all on one box (a PC, of course). :)

  4. Fiddler! Funny, I just featured it on a recent post myself, and I did find out about Fiddler from a fellow webdev at Y!.

    I use it on my windows test machine, and have been looking for a Mac OSX version as well. I took a look at paros which should be cross-platform (seeing as it’s Java) and looks like it can do somewhat the same things, but it wouldn’t work for me.

  5. The shareware application Charles is a full featured proxy-based web debugging tool. Written in Java, Charles runs the same on Mac OS X and Linux as it does Windows. Charles feature set is very similar to Fiddler’s with some neat additions including native AMF decoding, DNS spoofing (no more etc/hosts file editing!), bandwidth throttling, automatic browser proxy configuration, and a built-in reverse proxy server to just name a few additional features.

    I highly recommend Charles as it has saved me countless hours by quickly diagnosing tricky HTTP issues like multiple 301/302 redirects and cross-domain Flash problems. It’s well worth the shareware registration cost.

  6. I haven’t tried it much, but the Charles Proxy is similar to Fiddler, and works on Windows, Mac OS X, and Linux.

  7. I like ‘Charles Web Debugging Proxy’ more than Fiddler, it’s really powerful and cross-platform…

  8. Wireshark has a Mac OS/X version, or so it says. Sorry, I’m not a Mac person.

  9. Thanks to those who suggested Charles–I’m giving it a whirl on my personal machine and it looks quite robust!

    Really funky icon though.

  10. Fiddler comes with an “automatic proxy configuration” file. Fiddler rewrites this file when it opens and closes, so that it routes traffic through Fiddler when Fiddler is running, but doesn’t reference Fiddler when Fiddler is not running. Using this file is a much easier way to configure firefox to use fiddler, as you can configure it once and then just click “reload” when you want to change configurations.

  11. When I switched to infosec (webappsec) from s/w dev several months ago, I was pleasantly surprised that there are a few mature man-in-the-middle proxies that can do what Fiddler can, namely: WebScarab, Paros, burp. All are java based, and very much popular in real webapp vulnerability assessment activities by the actual hacker teams, ‘ethical’ or not. Try it, you might find them useful even for development.

  12. I should probably mention (since folks are still going to this post) that Fiddler now includes a Firefox add-on (called FiddlerHook). Manual configuration of Firefox’s proxy settings is no longer required; simply use the status bar panel to attach/detach from Fiddler.

  13. Thanks much on this wonderful piece! It has saved hours of many folks with whom I shared this info.