Lesser-Known JavaScript Debugging Techniques

After I prototype an app I’m building, my time is split between the editor and the browser with the console open. I try to debug as I go to avoid creating a complete mess. Moreover, when I get a bug report for a production app the first thing that I do is try to debug using Chrome devtools, and I usually find the bug without touching my editor. To be effective at that, I had to learn a great deal about the tools available and in this post I’m going to shed light on the lesser-known features and techniques of JavaScript debugging.

Command Line API

Started by Firebug and currently implemented in all browsers with a debugger. It has many useful utility functions such as $, $0, keys, values etc. and I highly encourage you to learn everything about them.

Until recently, Chrome DevTools didn’t implement the full API, and even after they did, a lot went undocumented. The most useful of those functions are:

debug and monitor

If you basically live in the console like I do you’d want to be able to add breakpoints to function references without having to go to the source and find the function, especially when debugging production apps with minified source or built source with no source maps.

debug(ExampleApp.exampleFunction)

Now every time the ExampleApp.exampleFunction is called the debugger will be invoked. To turn it off simply call undebug on the same function.

However, you often just need to know if the function was called and the arguments passed to it, for that you can use monitor and unmonitor.

Setting up traps

When working on a complex system with many modules, it’s impossible to know what every part is doing. Beyond the typical console.loging and breakpoint insertion, a good debugging technique is setting up traps with debugger statements to stop and get an idea of what’s going on.

For a long time I’ve had a library of functions that I copy-pasted around to help set up traps. But after a round of polishing I’m releasing it as a stand-alone JavaScript library and a chrome extension called Debug Utils. You can find it on GitHub and can install it directly from the Chrome Webstore.

Enter DebugUtils

Break on native method call

Unfortunately debug and monitor don’t work on native methods so you need to wrap native methods with functions containing a debugger statement, similar to the tweet above, except you probably would want to call the original function after the debugger statement. In DebugUtils this is called $dum (short for debug utils method).

$dum(Event.prototype, 'preventDefault');

Break on custom events

The Command Line API provides a monitorEvents function which is great for debugging DOM events, but it won’t work for custom events. For that you want to setup your own debugger or logger function as a handler to an event on an object. In DebugUtils this is called $duv (short for debug utils events).

$duv(exampleModule, 'data');

Break on property access

Often times, objects can start changing from under your feet. You can setup object getters and setters containing a debugger statement to find out what part of the code is responsible. When something changes a given property on your object you will stop and be able to trace back what’s changing it. In DebugUtils this is called $dus:

$dus(exampleObject, 'someProperty');

You can also break on property read using $dug.

For more documentation and information on DebugUtils, be sure to check out the Github project. Happy debugging!

Edit: My EmpireJS talk on this subject