Skip to content

Instantly share code, notes, and snippets.

@carols10cents
Last active October 5, 2016 14:20
Show Gist options
  • Save carols10cents/d3c9d923e028137ecb32af529c25866d to your computer and use it in GitHub Desktop.
Save carols10cents/d3c9d923e028137ecb32af529c25866d to your computer and use it in GitHub Desktop.
My treatise on debugging

This was written a while ago for an internal work wiki, links may not work and recommendations may be dated. Also see this talk that Jake and I did about this topic!

Debugging

The first rule of debugging is don't panic. Computers only do what you tell them to do. There should be nothing mysterious or magical about what your code is doing. There are many resources at your fingertips to be able to logically and definitively identify and fix a problem in your code.

The second rule of debugging is print. Even if you don't think there's any possibility that what's being processed at any point in time is different than what you think is being processed, print it out anyway. Print out values for your variables and inputs to your functions at various points in time.

Which brings us to the third rule of debugging-- narrow it down. If you print out values at 3 locations and the values at the 1st spot are what you expected but they're wrong at the 2nd, then you can eliminate the code run before the 1st spot as the cause of the problem, set aside the code after the 2nd spot for the moment, and concentrate on the code between 1 and 2 since you've just proven that there's a problem between those points. If the code here is still too complex, repeat the process by printing out the values in 3 places between 1 and 2. Another way to narrow down a problem is to try and reproduce a specific issue independently of your entire application. This is particularly useful when trying to prove that the problem lies in another person's code-- they are more likely to acknowledge there is a deficiency in their code if you can provide a small, simple distillation of the issue. Otherwise they are likely to assume it's an issue with your code or the interaction between the two, since they know their code but don't know yours.

Reading error messages

When you have an error in your code, you'll often get a whole bunch of errors at once. The important thing to remember is to start reading from the top and fix the first problem you see, because the rest of the problems may be caused by that first problem.

In CSS

So it's a little hard to "print" things out in CSS, but you can do it in a way, especially with positioning issues-- add some borders or backgrounds to your <div>s or other elements to see where they're ACTUALLY ending up. Isolating problems is also important since you might have many interactions going on-- do this by either removing markup and CSS one item at a time until the problem no longer occurs, or start with very simple markup with no CSS and add items until you can reproduce the problem.

Common errors

  • Incorrect Precedence
  • Using properties or values that don't exist: If you're not sure if the style you're trying to get is whitespace:no-wrap; or white-space:nowrap;, don't waste time trying random things out until you happen upon the right one. Look it up.
  • Id vs class: If you have <div id="foo">, you need to use the pound symbol to use the ID: div#foo { .... If you have <div class="bar">, use a period to use the class: div.bar { .... This is something you need to know right off the bat to be able to use CSS at all, but still something that's easy to mess up.

Firebug

Get the Firebug extension for Firefox. Also see this Firebug tutorial.

Once you have the extension installed, go to the webpage you're having problems with and click on the bug in the lower right hand corner of Firefox. The Firebug window will expand out from the bottom.

Click on the Inspect button (leftmost button in the top bar of the Firebug window). Now click on an element in your page that you're having the problem with, or the closest parent, child or sibling element that you are able to select.

You should now see two main areas in the Firefox window. The left hand area should have the HTML tab selected and you should see the collapsible, color coded HTML of your page with the element you just inspected highlighted. In the right hand area, the Style tag should be selected and you will see all the rules in your CSS that apply to that element.

If the element currently selected isn't the exact element you want, you can navigate up and down the tree of the HTML in the left hand area until you have found and selected the element you're interested in. Hovering over node names will highlight that node on the page in blue (including its margin in yellow and padding in purple-- this highlighting alone can be instrumental in identifying where a positioning problem should be corrected).

Once you have your element selected, take a look at the style rules in the right hand area. Rules that have been overridden by other rules of higher precedence or later position are struck out (see Andrew's BBL notes for more on precedence). This can help you find the common problem of a rule not seeming to apply because another rule is overriding it.

Also in the right hand area, you can click just to the left of any style rule to disable it temporarily-- you should see a grey circle with a diagonal line through it when you hover there and a red circle with a diagonal line through it when you've clicked it. This will strike out that rule and disable the rule on the page. This is useful for identifying rules that are causing the problems or unintended interactions with other rules. You can click on the red circle to reenable the rule, and if you reload the page all the temporarily disabled CSS rules will be reinstated.

You can also change the values of rules or add new rules by clicking on them in the right hand side. This is a quick way to change the CSS on the page without having to edit your code and reload.

In JavaScript

A List Apart wrote a great article on debugging JavaScript with an example that will walk you through many advanced techniques.

Common Errors

  • Not putting a closing single or double quote at the end of the string
  • Not putting a closing parenthesis or curly brace, or having an extra parenthesis or curly brace
  • Using a single equals sign to compare values instead of double (value only) or triple (value and type) equal signs
  • Not putting a semicolon at the end of a statement

Reading error messages

There are a few ways to view javascript error messages.

  • Firebug: If you have javascript errors on a page and you have the Firebug Firefox extension, the bug icon in the lower right will change to a red X with the number of errors (see next section). Click on that to open the Firebug panel and go to the Console tab (you may need to enable the console tab for the page you are looking at). The errors should be listed on this tab. They can sometimes be expanded to get more details, and sometimes the link with the error will take you to the appropriate line in your code on the Script tab (but this doesn't always seem to work).
  • Firefox error console: To open the Firefox error console, go to the Tools menu and select Error Console. You can view all messages or only errors, warnings, or messages. The errors tab will list the error and potentially the file and line number of the error.

Like mentioned before, it's important to start reading and fixing error messages from the top of the list because the subsequent errors may be due to the first error and fixing that one will fix all of them. Also keep in mind that if one part of your javascript is broken, it may affect all javascript after that, so all javascript in your page may break even though the problem might only be in one function.

Here's a real life error message from Firebug:

 unterminated string literal
 document.write('blah);\n

"Unterminated string literal" means we forgot to end single or double quotes somewhere, and indeed, in the line displayed there should be another single quote after blah.

In General

The Firebug extension for Firefox is not only great for figuring out CSS, it's also great for debugging JavaScript! Once you've downloaded and installed it, expand the Firebug panel by clicking on the bug in the lower right hand corner of your Firefox window. Also see this Firebug tutorial.

If you have JavaScript errors in the current page, there won't be a little bug in the corner-- it'll have a red X and say "1 error". Click on that instead.

For JavaScript, go to the Script tab and enable script debugging if it says it is disabled for the page you are viewing. You should now see some of the script for the current webpage in the left panel.

If you have multiple external javascript files that you are calling in your page, choose the file you're interested in by clicking on the URL in the top bar in Firebug. This will bring up a menu of all the files you've included that will let you switch between them.

Either scroll down in the left hand window or search for the function you're trying to debug by using the field with the magnifying glass in the top bar in Firebug on the right hand side.

Once you've found the function you're interested in, you can create break points. These are spots where the code will just stop running when it gets there, and Firebug will display the values of all the current variables. The code will stay paused there until you tell it to continue. By placing multiple break points in a small area, you can narrow down where a problem is happening. By placing break points right before where you're getting an error, you can see what happens to lead up to that error.

Let's try it out. Set some break points by clicking on the line numbers to the left of some of the lines in that function. When a break point is set at a line, there will be a red dot to the left of the line number. Add as many as you'd like-- they're free!

One important thing to note is that nothing will happen with these break points until this code is run. If you do whatever you think you need to do to trigger the function where you have placed the break points but the code never stops at those points, that tells you the code isn't even being triggered and you should move your debugging efforts to the spot at which you think your code should be being called.

When your code hits a break point, that line will be highlighted and there will be a yellow triangle on top of the red dot next to the line number. Now, if you look in the right hand panel in Firebug, you'll see all the variables that are in the current scope and what they currently contain. This is where you can see if what YOU think should be in the variables matches what IS in the variables at this point in time.

When you're ready to continue running the code from the break point, click on the blue triangle button that looks like a play button on your VCR (or DVD player for you young whippersnappers) that's in the top bar of Firebug to the left of the magnifying glass field. If you have more break points set, Firebug will run the code until it gets to the next break point. If there are no more break points to hit, it will finish running all the code it is supposed to and you won't see any more yellow triangles over the red dots and the blue play button will be grayed out.

A simple technique that is browser independent:

  alert('value of variable t = ' + t);

This will stop your code and pop up a dialog box (alert) with the text you specify. The disadvantage of this is that you have to click "Ok" in the dialog box whenever this happens-- and that might get a bit tiresome.

AJAX

When making requests from within the Javascript on your page and then using the result on the page, it's important to isolate the following things from each other to figure out where the problem is happening:

  • The event that triggers the request
  • The HTTP request
  • The data returned from the request
  • How that data is processed/interpreted
  • How the processed/interpreted data is displayed

The trigger event and how the returned data is processed usually falls under the generic Javascript category, of which the debugging techniques are detailed above. The display of the data could be a CSS, HTML, Javascript, or other problem-- it would be hard to say without knowing the specific situation.

However, the HTTP request and the data returned are the parts not covered by other sections on this page and are most specific to AJAX. Since many other areas on this page have recommended Firebug, this section is going to explain how to use Firebug as well-- but there are other extensions and applications that do pretty much the same thing, such as Live HTTP Headers and Charles.

In Firebug, go to the Console tab (and make sure it's enabled for the current site). Trigger the AJAX request-- you should see a line added to the Console tab that starts with the method of your request (GET/POST) and then has the URL (abbreviated) and how long the request took. If you did not see a line like this appear, or if you saw a Javascript error instead, you know that your problem is in how the request is triggered.

At the beginning of the line is a plus sign which will expand that particular request. In the expanded view, there are three tabs. The "params" tab will show the CGI parameters of the request and their value. The "headers" tab will have the headers from the request and the response. The "response" tab will have the data that was returned from the request. You can use these three tabs to make sure there were no errors and to make sure everything is what you expect.

Another useful thing may be to only run the request in your browser. To do this, you can right click on the URL of that request on the Console tab and either open it in a new tab or copy the URL to the clipboard. The advantages of having just that request open are 1, that you can change things in the code and rerun just that request with the exact same values without having to generate the same request again in your application, and 2, that you can view the output outside of the small Firebug panel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment