Chapter 25
What to Do When It Won't Work: Debugging Your Scripts

In This Chapter

Bugs! Bugs! Bugs!

Whether it's ants at a picnic or cockroaches in the closet, bugs aren't most people's favorite critters. They get in things, spoil things, and generally cause a great deal of consternation. Their appearance usually gets a standard response: insecticide, a fly swatter, or a call to the exterminator. Bugs just aren't popular—unless maybe you're a bug collector. (Any bug collectors out there, please accept my apology; I'll use the proper term: entomologist.)

Computer programs are often much like life: Programs don't always work, and when they don't, it is said (in another humorous adaptation by programmers of yore), "This program has a bug." Whether you have termites in your walls or errors in your code, a bug is a bug, and a bug isn't good.

As you embark down the path to JavaScript enlightenment, you'll no doubt encounter a few bugs of your own. In the next few pages, you'll take a look at some of the more common causes of bugs and how to exterminate them.

The End Result

A bug can occur in two forms, one of which is sometimes more insidious than the other. The first sort of bug makes itself quite obvious—like a cockroach in the middle of the kitchen. These bugs prevent the program from executing beyond a certain point due to some illegal statement. JavaScript can recognize these and attempt to scold you, as you will learn shortly.

The more insidious bugs, perhaps not unlike termites deep in the foundation, are those that are not illegal statements but are based on incorrect logic. Your program executes because the statements are "legal," but the results are incorrect because your programming logic was flawed at some point. These can be extremely difficult to exterminate. We'll discuss such nasties second.

BZZT! The ERROR

When your bug is the result of an illegal statement, JavaScript will holler at you with a big pop-up alert box like the one shown here.

A JavaScript error message.

The first line of the error window identifies the file (or URL) where the bug occurred, while the second line tries to identify the bug. In this figure, the real problem was that a built-in JavaScript function was misspelled—but the error states that the function (as it was misspelled) was "not defined." This is the browser's way of saying, "I can't find a function by that name," and it makes an important point: errors that you may get in JavaScript will help tell where the bug occurred, but they may not tell you exactly what the error was. Therefore, figuring out what caused an error will sometimes require a bit of sleuthing.

Another thing you might notice is that the first line ends with the word "line" and a number. This is the line number in the HTML document where the error was found, which should at least help you find its location. Note that every line of the HTML file is counted as one line (not just those containing JavaScript code). Sometimes the URL is longer than the error window, and a scroll bar will appear so you can scroll within the error window to see the whole message.

Because illegal statement errors are often the easier bugs to get rid of, the previous information is half the battle if not more. JavaScript has already told you where and in which statement the problem lies. Thus, you can spelunk into the code to where the bug resides with some accuracy. From there, your final mission (which you should choose to accept) is to determine why the noted statement is illegal. There are several possibilities you should consider; they are detailed in the following sections.

Tpyo...er...Tipo...uh...Spelling Errors

By far, the most common source of bugs is the typographical error. In a word: that darned misspelling. Unlike humans, who can still get the general idea of what you're trying to say (whether you remember to put the "i" before the "e" or not), computers aren't so flexible. If it isn't spelled exactly right, the computer doesn't have a clue what you mean. The problem with "typos," as they're called, is that (as you saw in the previous section) the browser isn't smart enough to say, "Ahh, you didn't spell it right." If it were, the browser would know what the right value was...right?

Instead, a typo can cause one of several things to happen:

And the list goes on...and on...and on. In a nutshell, spelling something wrong is a lot like trying to order food in a French bistro when you don't speak French: Depending on what word you get wrong, you could end up with anything from a scoop of sorbet to a boiled shoe. Check your spelling!

A Capital Idea

"Kissin' cousins" to spelling errors are errors in capitalization. The JavaScript documentation notes that JavaScript is case-sensitive (upper- and lowercase matter). Case is important, and capitalization is critical.

Many functions, methods, and properties in JavaScript are "compound words" made up of multiple words slapped together (for example, getDate()). In most cases, the second word is capitalized while the first word is not. If you try to type in a JavaScript component and don't capitalize the second (or third, or fourth) word, you'll probably generate an error.

FYI...
Appendix A, "JavaScript: The Complete Overview," lists all the components of JavaScript. In addition, Chapters 5 through 17 show the proper capitalization for JavaScript functions, objects, and properties.

Matching Mates

On many occasions in JavaScript programming, you use paired bookends, such as brackets { }, parentheses ( ), and both single- and double-quotation marks. As with socks in the laundry, improperly matched pairs will result in a statement of problematic fashion. It is vital that every open bracket and parenthesis have an appropriate closing mate somewhere further down in the code. People most often lose track when they are nesting parentheses or brackets, such as when they are using a loop statement within a loop statement.

It is not uncommon to find multiple closing parentheses or brackets at the end of a series of statements; each one pairs up with an opening mate that appears earlier. It might look strange, but an eye for an eye and a bracket for a bracket, as they say (don't they?). Well, it’s something to watch for.

JavaScript Errors

If you're still stumped and you're positive you spelled everything correctly, move on to Phase 2: Interpreting the JavaScript error message. JavaScript has a handful of errors that it kicks up for a variety of situations. Take a look at each and note what to check for if you encounter one. For purposes of the "error lineup," look at the second line of text displayed in the error window. Any parts of the message that may change will be represented by a string of question marks (?????).

????? Is Not Defined

????? Is Not a Function

????? Is Not a Numeric Literal

The Dreaded Crash

Sometimes things get really hairy, and you're presented with the infamous "illegal operation" dialog box.

This message means that something’s seriously wrong!

After you see this message, Netscape or Internet Explorer itself shuts down. First rule: don't panic. Chances are you've made some simple mistake, and although the browser should have a better way of handling it, instead it charges forward blindly until it gets hopelessly stuck.

A common way to cause this error (if you really like creating bugs instead of fixing them) is to try to treat a numeric value like a string and manipulate it. For example, this code

var n = 264;
document.write(n.substring(0, 1));

will definitely cause a crash. However, if you convert the number to a string first, like this

var n = 264;
var strN = "" + n;
document.write(strN.substring(0, 1));

then everything's fine.

Along the same lines, calling a method of a numeric variable (even if it's not a string method) may cause the browser to explode. There isn't any "solution." Rather, the best thing to do is to live by the punch line to that old joke: don't do it. Actually, the fault isn't yours, it's the browser's—it should generate an error in such circumstances, not crash. Presumably, future browser revisions will weed out these landmines. On the other hand, they may also introduce others. Fortunately, at least, you won’t be the only one to discover the problem, and if a browser has a true defect, it will become well known in the JavaScript support areas (newsgroups, mailing lists, Web pages, etc).

Design Errors (or “Why Did My House Just Collapse?”)

Often sneakier and much more difficult to track down are outcome bugs. These do not result from an illegal statement that JavaScript cannot understand. They are the results of errors in program design, which produce the wrong results when you execute the program.

Think of an entire JavaScript program (or any computer program, for that matter) as a large exercise in logic and grammar. Even if your grammar is impeccable (JavaScript makes no error complaints), your logic may be flawed. It may be flawed in one tiny section of code or in several tiny sections of code, or your entire design might be logically flawed.

Ultimately, the only solution to these problems requires three possible steps:
  1. Locate the region of code likely to contain the design flaw.
  2. Follow the logic, and then redesign where necessary.
  3. Return to step 1 if the problem persists.

Finding the Holes Where the Rain Gets In

Suppose you've written a JavaScript program that calculates a loan payment schedule. The program contains no syntax errors, but the alleged payment amount it reports is clearly incorrect. You have a design flaw (don't feel too depressed; virtually every program contains some design flaw the first time around).

To locate the region of code where the flaw most likely is, you have to consider the program itself. Presumably, you have several functions in such a program, each of which performs some calculation. Therefore, any of those would make good suspects at this point; after all, a wrong final tally is probably caused by an erroneous calculation.

Look at the sections of code you might suspect. Read them over carefully and follow the logic in your mind. If no flaw is immediately apparent, dip into the programmer's toolbox for handy debugging tool number one: the inside scooper.

One of the most revealing ways to track down design bugs is to gain some insight into what is going on "behind the scenes" while the program executes. A very common way to do this is to stick new lines of code here and there that display the current values of particular variables. This way, when you execute the program again, you have a better idea of what is going on "in there." In JavaScript, you can do this using the window.alert() method. For example, imagine that the suspect code looks like this:

When the program executes again, the values for those variables are displayed, giving you a clue as to whether they are at least what you were expecting them to be. If they aren't, you must begin your investigation again, but at least you've narrowed it down. (Do remember, though, to remove these lines of code once the program is working because they're not intended to be part of the final program.)

In addition to variable values, another common test is for program flow. Did the execution even reach your function? Perhaps your function was never even executed because of some other design flaw in your logic. You can easily test for this just as you did before: somewhere within the questionable function, stick a line that you're sure will generate some action if the function is, in fact, being executed. You could insert the line window.alert ("Hi function bob was just called"), for instance.

Sigh and Rebuild

Using some combination of the previous example—perhaps many times, if necessary—you will eventually track down the region of code that is logically flawed. From there, you must identify the flaw and rebuild to correct it. Once you're certain you have the right portion of code, the only sure way to identify the flaw, is to step through it mentally, bit by bit. In a Zen-like way, imagine that you are the computer, and attempt to interpret the code exactly as the computer would. You might even grab a pencil and paper and write down the values of variables as you progress through your mental exercise. This can be very tough work. Sometimes the logic flaw will pop out at you quickly. In a most difficult case, however, you might be completely stumped. This is the "art" of programming.

A clear head always helps, so time away from the screen can be a benefit. Equally useful are smart people—or at least experienced ones; there are many places on the Internet where people exchange programming hints and pose questions to others. Check out the UseNet newsgroup comp.lang.javascript for just such chatter and support.

The Mighty Debugger

Internet Explorer users are often on the short end of the stick when it comes to JavaScript support, but when it comes to bug extermination, you’re in for a treat. Microsoft has recently released a free JavaScript debugger utility, which you can download from:

Once you download and install the debugger, it hooks into Internet Explorer’s View, Source feature. Additionally, it will also pop up anytime Internet Explorer runs into an error when executing a JavaScript program.

But what is this debugger? In short, it is a small utility that helps you follow the logic and flow of the JavaScript program. Like a programmer’s VCR, when the debugger is launched you can “freeze frame” or “step forward” and “step back” through the JavaScript code. The debugger shows which line of code is currently being executed. In this way, you can see where if...then clauses are leading to, how loops are functioning, and so on. This is an excellent way to find out when a program is skipping a bit of code or going to a different bit of code than you anticipated. And once you find the problem, you can fix your program so that it flows correctly.

Remember, though, that the Microsoft Debugger only works with Internet Explorer, not Netscape Navigator. This does limit its usefulness, because Netscape Navigator is the better browser for running JavaScript programs on. Perhaps a debugger will be released for Navigator as well. Perhaps one already has been by the time you read this!

The Least You Need to Know

Bugs are a common problem when you're creating any type of program, and a JavaScript program is no exception. JavaScript tries to provide information on where the bug is and what it is, but it doesn’t always offer the most accurate analysis of the problem. Furthermore, some bugs can generate errors that makes no sense whatsoever—unless you understand a few tricks.

For the most part, mistakes in spelling or capitalization are the worst culprits when it comes to bugs. The three questions you, as a JavaScripter, should ask are:

If your code is free from grammatical errors, it might be suffering from design flaw. You need to examine the logic of your code. For that purpose, you might try these suggestions:

Previous Chapter Next Chapter


Beginning of ChapterTable of ContentsBook Home PageQue Home Page


For comments or technical support for our books and software, select Talk to Us.
To order books, call us at 800-716-0044 or 317-228-4366.

© 1997, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon & Schuster Company.