Skip to content

Instantly share code, notes, and snippets.

@MarkBennett
Created January 17, 2012 21:44
Show Gist options
  • Save MarkBennett/1629116 to your computer and use it in GitHub Desktop.
Save MarkBennett/1629116 to your computer and use it in GitHub Desktop.
Debugging JavaScript In the Trenches

Into the Trenches: Debugging JavaScript in the Browser

Anyone who has written JavaScript for the web browser knows the frustrations you can experience while debugging it. This gist is collection of JavaScript debugging tips I've used and collected. Please fork, contribute and share.

Were possible I cite sources, however I apologize to anyone that I've missed.

If you'd like to try these tips out as you read, jsFiddle can handle gists:

http://jsfiddle.net/gh/gist/jquery/1.7/1629116/

Firebug Command Line API (Firebug, Chrome, ~IE, ~Firefox)

This API may have started in Firebug but is fully supported in many other browsers. Use it to quickly query the DOM, inspect objects, and retrieve references to elements selected in the inspector.

http://getfirebug.com/wiki/index.php/Command_Line_AP

JSFiddle (all browsers)

Being able to debug JavaScript often means reducing an error to it's most basic components. JSFiddle is a great way to do so, and then communicate this to other collaborators. You can signup to link fiddles your profile.

TIP: If you're going to share the fiddle with others and plan on updating it, remember to set your latest version as the base!

TIP: You can create a fiddle from a gist. See http://doc.jsfiddle.net/use/gist_read.html

http://jsfiddle.net/ http://jsfiddle.net/gh/gist/jquery/1.7/1629116/ http://jsfiddle.net/MarkBennett/YpQKS/

console.dir() (Firebug, Chrome, IE, Firefox)

console.log() is great for recording strings, but sometimes you want to see a proper representation of a JS object. Use console.dir() to see an ineractive representation of a JS object.

This can also be useful for working with jQuery objects which are sometimes hard to distinguish from Array objects using console.log().

console.dirxml() (Firebug, Chrome)

Web developers think in markup, so sometimes you want to see DOM objects in an xml format. dirxml() is there for you.

Selecting elements with $0, $1, $2, ... (Chrome, Firefox)

Sometimes you haven't worked out the right query to select and element yet. In that case, try inspecting it in the Developer Tools. Select the element you're interested in from the Elements tab, then reference it in your JavaScript using $0. Previous selections map to $1, $2, etc.

monitorEvents() (Chrome, Firebug)

Logs to the console events which are triggered on an object. For example, monitorEvents(window, "key") logs key events.

debugger keyword (Firebug, Chrome)

Setting breakpoints in your browser is great, but sometimes you need to conditional trigger debugging. Using the debugger keyword you can invoke your browser script debugging from your source. Just don't forget to remove these calls before you hit production!

Remote Debugging with JSConsole (all browsers)

When remote debugging isn't available the next best option is JSConsole.com. You can launch it on your desktop, then insert a script tag into the page you would like to debug. You can then run JavaScript commands in the browser on your desktop and see the results of running the JavaScript in the page you're debugging.

http://jsconsole.com/remote-debugging.html

Track client-side errors with Analytics (All)

This tip comes from Aicke Schulz, who suggested using GA's _trackEvent() call to capture errors from window.onerror in your Analytics stats.

To quote Aicke,

"""

I'm using _trackEvent() from Google Analytics to capture errors from window.onerror. So I can see errors which appear at the user, in every environment. This shouldn't happen that much, but sometimes it does. Good to see if you mistakenly forgot to remove a debug output or forgot to check if an object exists. And you get all the browser informations by ga itself and the ability to filter the errors is quite useful.

Tip 1: Limit the reporting to your own scripts, by checking the domain of the script/file where the error occured in
Tip 2: Check if message and file are not undefined and row > 0 (some browser report bugs in line 0, but there can't be an error)
Tip 3: Do not report errors from browser you do not support (e.g.: < IE7 or < FF3.6)
Tip 4: set opt_noninteraction = true, otherwise every error will influence your bounce rate

To track the event I use:

_gaq.push(['_trackEvent', 'Script Error', message, file + ": Line " + row, undefined, undefined, true]);

"""

I've set this up on http://yegrb.com if you want an example.

https://plus.google.com/104431949275766772757/posts/N1qwzwuAZd1 https://plus.google.com/110776836375046575411/posts

XHR Logging (Chrome)

Turn it on by right-clicking in the console.

XHR breakpoints (Chrome)

Debugging communications with the server can be slow and painstaking, especially if you don't have access to your server logs. By setting an XHR breakpoint you can inspect the request send from your browser directly to ensure it's being formatted properly. This is also a good tool for tracking down errand XHR requests in your application. It can be restricted by URL if you don't want to see all requests.

DOM breakpoints (Chrome)

Curious which JavaScript code is modifying your DOM elements? You can right-click an element the inspector and then break when it's attributes or sub-tree are modified, or when it's removed.

Pause on exceptions (Chrome)

Investigating exceptions in your code can be tricky. Chrome lets you set JS breakpoints on handled and unhandled exceptions.

Preserve console

TODO

JSBeautifier.org

When your browser doesn't pretty print JavaScript, there's a website that will!

http://jsbeautifier.org/

Edit JavaScript On-The-Fly (Chrome)

Think you know what's causing an exception, with Chrome you can edit your JavaScript without reloading the page to test your changes.

Pretty print minified JavaScript (Chrome)

Are you debugging minified code in production? This can't restore your original variable names, but it will add spacing and breakpoints to make the source more readable while you debug.

Webkit Remote Debugging (Chrome, Playbook, more soon?)

A remote debugging protocol is now supported in WebKit and is slowly being added to WebKit based products. This allows you to connect Developer Tools to instances of WebKit running on another device on your network. Both iOS and Android are expected to support this in future releases but have made no specific announcements.

http://www.webkit.org/blog/1620/webkit-remote-debugging/

about:debug (Android 2.3+)

Enter about:debug in the url then check your settings. Try outputting to the console.

How to contribute

Sources

I would especially like to thank:

<h1>Debugging JavaScript In The Trenches</h1>
<div id="bulls_eye">Good shooting!</div>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<div id="ajax_target">
</div>
<p>You can also find this in it's own <a href="http://jsfiddle.net/MarkBennett/YpQKS/">fiddle</a>.</p>
<p><em>Edited in c9</em></p>
$(function() {
var list = ["One","Two","Three"],
new_list = $("li").map(function() { return $(this).text(); }),
my_div = window.document.getElementById("bulls_eye");
$.ajax({
url: "/gh/gist/response.json/1629116/",
success: function(data, status, jqXHR) {
console.log("AJAX SUCCESS! " + status + ": " + data.message);
$("#ajax_target").text(data.message);
},
dataType: 'json'
});
// I handle an exception without you ever knowing!
function exceptional() {
try {
throw "Bad mojo!";
} catch (e) {
// I don't care about no stinkin' exception!
console.log("he he he...");
}
}
exceptional();
// TAKE THIS OUT IN PRODUCTION
debugger;
// Things to try
//
// console.log(list)
// console.log(new_list)
//
// console.dir(list)
// console.dir(new_list)
//
// Inspect an element in the developer tools then try, $0
//
// console.monitorEvents(my_div, "mouse")
});
name: Debugging JavaScript In The Trenches
description: This is a sample I plan on using during my JS debugging talk at YEGrb.
authors:
- Mark Bennett
resources:
- https://plus.google.com/104431949275766772757/posts/N1qwzwuAZd1
normalize_css: yes
{
"message":"Hello, from the Gist!"
}
<!DOCTYPE html>
<!--
Google HTML5 slide template
Authors: Luke Mahé (code)
Marcin Wichary (code and design)
Dominic Mazzoni (browser compatibility)
Charles Chen (ChromeVox support)
URL: http://code.google.com/p/html5slides/
-->
<html>
<head>
<title>Presentation</title>
<meta charset='utf-8'>
<script
src='http://html5slides.googlecode.com/svn/trunk/slides.js'></script>
</head>
<style>
/* Your individual styles here, or just use inline styles if that’s
what you want. */
</style>
<body style='display: none'>
<section class='slides layout-regular template-default'>
<!-- Your slides (<article>s) go here. Delete or comment out the
slides below. -->
<article class='biglogo'>
</article>
<article>
<h1>
Title Goes Here Up
<br>
To Two Lines
</h1>
<p>
Sergey Brin
<br>
May 10, 2011
</p>
</article>
<article>
<p>
This is a slide with just text. This is a slide with just text.
This is a slide with just text. This is a slide with just text.
This is a slide with just text. This is a slide with just text.
</p>
<p>
There is more text just underneath.
</p>
</article>
<article>
<h3>
Simple slide with header and text
</h3>
<p>
This is a slide with just text. This is a slide with just text.
This is a slide with just text. This is a slide with just text.
This is a slide with just text. This is a slide with just text.
</p>
<p>
There is more text just underneath with a <code>code sample: 5px</code>.
</p>
</article>
<article class='smaller'>
<h3>
Simple slide with header and text (small font)
</h3>
<p>
This is a slide with just text. This is a slide with just text.
This is a slide with just text. This is a slide with just text.
This is a slide with just text. This is a slide with just text.
</p>
<p>
There is more text just underneath with a <code>code sample: 5px</code>.
</p>
</article>
<article>
<h3>
Slide with bullet points and a longer title, just because we
can make it longer
</h3>
<ul>
<li>
Use this template to create your presentation
</li>
<li>
Use the provided color palette, box and arrow graphics, and
chart styles
</li>
<li>
Instructions are provided to assist you in using this
presentation template effectively
</li>
<li>
At all times strive to maintain Google's corporate look and feel
</li>
</ul>
</article>
<article>
<h3>
Slide with bullet points that builds
</h3>
<ul class="build">
<li>
This is an example of a list
</li>
<li>
The list items fade in
</li>
<li>
Last one!
</li>
</ul>
<div class="build">
<p>Any element with child nodes can build.</p>
<p>It doesn't have to be a list.</p>
</div>
</article>
<article class='smaller'>
<h3>
Slide with bullet points (small font)
</h3>
<ul>
<li>
Use this template to create your presentation
<li>
Use the provided color palette, box and arrow graphics, and
chart styles
<li>
Instructions are provided to assist you in using this
presentation template effectively
<li>
At all times strive to maintain Google's corporate look and feel
</ul>
</article>
<article>
<h3>
Slide with a table
</h3>
<table>
<tr>
<th>
Name
<th>
Occupation
<tr>
<td>
Luke Mahé
<td>
V.P. of Keepin’ It Real
<tr>
<td>
Marcin Wichary
<td>
The Michael Bay of Doodles
</table>
</article>
<article class='smaller'>
<h3>
Slide with a table (smaller text)
</h3>
<table>
<tr>
<th>
Name
<th>
Occupation
<tr>
<td>
Luke Mahé
<td>
V.P. of Keepin’ It Real
<tr>
<td>
Marcin Wichary
<td>
The Michael Bay of Doodles
</table>
</article>
<article>
<h3>
Styles
</h3>
<ul>
<li>
<span class='red'>class="red"</span>
<li>
<span class='blue'>class="blue"</span>
<li>
<span class='green'>class="green"</span>
<li>
<span class='yellow'>class="yellow"</span>
<li>
<span class='black'>class="black"</span>
<li>
<span class='white'>class="white"</span>
<li>
<b>bold</b> and <i>italic</i>
</ul>
</article>
<article>
<h2>
Segue slide
</h2>
</article>
<article>
<h3>
Slide with an image
</h3>
<p>
<img style='height: 500px' src='images/example-graph.png'>
</p>
<div class='source'>
Source: Sergey Brin
</div>
</article>
<article>
<h3>
Slide with an image (centered)
</h3>
<p>
<img class='centered' style='height: 500px' src='images/example-graph.png'>
</p>
<div class='source'>
Source: Larry Page
</div>
</article>
<article class='fill'>
<h3>
Image filling the slide (with optional header)
</h3>
<p>
<img src='images/example-cat.jpg'>
</p>
<div class='source white'>
Source: Eric Schmidt
</div>
</article>
<article>
<h3>
This slide has some code
</h3>
<section>
<pre>
&lt;script type='text/javascript'&gt;
// Say hello world until the user starts questioning
// the meaningfulness of their existence.
function helloWorld(world) {
for (var i = 42; --i &gt;= 0;) {
alert('Hello ' + String(world));
}
}
&lt;/script&gt;
&lt;style&gt;
p { color: pink }
b { color: blue }
u { color: 'umber' }
&lt;/style&gt;
</pre>
</section>
</article>
<article class='smaller'>
<h3>
This slide has some code (small font)
</h3>
<section>
<pre>
&lt;script type='text/javascript'&gt;
// Say hello world until the user starts questioning
// the meaningfulness of their existence.
function helloWorld(world) {
for (var i = 42; --i &gt;= 0;) {
alert('Hello ' + String(world));
}
}
&lt;/script&gt;
&lt;style&gt;
p { color: pink }
b { color: blue }
u { color: 'umber' }
&lt;/style&gt;
</pre>
</section>
</article>
<article>
<q>
The best way to predict the future is to invent it.
</q>
<div class='author'>
Alan Kay
</div>
</article>
<article class='smaller'>
<q>
A distributed system is one in which the failure of a computer
you didn’t even know existed can render your own computer unusable.
</q>
<div class='author'>
Leslie Lamport
</div>
</article>
<article class='nobackground'>
<h3>
A slide with an embed + title
</h3>
<iframe src='http://www.google.com/doodle4google/history.html'></iframe>
</article>
<article class='nobackground'>
<iframe src='http://www.google.com/doodle4google/history.html'></iframe>
</article>
<article class='fill'>
<h3>
Full-slide embed with (optional) slide title on top
</h3>
<iframe src='http://www.google.com/doodle4google/history.html'></iframe>
</article>
<article>
<h3>
Thank you!
</h3>
<ul>
<li>
<a href='http://www.google.com'>google.com</a>
</ul>
</article>
</section>
</body>
</html>
Copyright (C) 2012 Mark Bennett, Paul Irish, Aicke Schulz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment