





















































Unfortunately, today’s tools for client-side debugging and tracing aren’t as evolved as their server-side counterparts. For example, things such as capturing ongoing communication traffic between the client and the server, or client-side debugging, aren’t usually supported by today’s IDEs (Integrated Development Environments) such as Microsoft Visual Studio 2005. The next version of Visual Studio (code-named Orcas at the time of writing) promises a lot of improvements in this area:
These are only the most important new coming features; there are others as well. For more information we suggest that you browse and keep an eye on Scott Guthrie’s blog at http://weblogs.asp.net/scottgu/, the JScript blog at http://blogs.msdn.com/jscript/, Bertrand Le Roy’s blog at http://weblogs.asp.net/bleroy/.
Until this new edition of Visual Studio is released, we can rely on third-party tools that can do a very good job at helping us develop our AJAX applications. You’ll find a number of tools for Internet Explorer and Mozilla Firefox for this purpose.
The common practices for debugging JavaScript code are:
While the first option is straightforward, the second option offers a centralized place for storing different messages and could be considered more appropriate. Nevertheless both options can come in quite handy depending on the circumstances.
Microsoft AJAX Library offers the Sys.Debug object that has a series of methods that you can use for debugging and tracing. The diagram of this class is presented in figure below.
The Debug class
As we can easily see in the diagram, Sys.Debug offers the most common features that we can find also in other languages: assert(), trace(), traceDump(), fail(), and clearTrace().
assert(), trace(), and fail() automatically send the messages to the debugging console of the browser. To see the messages in IE you need to have the Web Development Helper, and for Firefox you need the Firebug plugin. Both of these tools are presented later in this article. Internally assert() calls fail() if the expression evaluates to false. fail() simply logs the message passed in by assert to the debugging console.
trace() offers an interesting feature beside logging to the debugging console: it offers the possibility to log the trace message in a <textarea> element with the ID TraceConsole. If such an element is found, trace() will log this message in this element too.
The clearTrace() function simply clears the TraceConsole element, if found.
The traceDump() function traces all the information about an object including its properties. Internally this function uses the trace() function so that we can have the information logged in the browser’s debugging console, and in the TraceConsole element (if it exists).
You might have wondered why the Microsoft AJAX Library comes with both release and debug version of the JavaScript file. The major features of the debug version of the library files are:
Once the development stage is finished, you can switch your application to the release version of the script (MicrosoftAjax.js), which is smaller and doesn’t contain the debugging features presented above.
Perhaps the most interesting features of the debug version are the last two: debugging-friendly information and parameter validation.
We will explain these two concepts by taking a look at how different functions are defined in the debug and release version of the library. The debug version of the library contains:
function Sys$_Debug$assert(condition, message, displayCaller) {
...
}
Sys._Debug.prototype = {
assert: Sys$_Debug$assert,
...
}
and:
String.format = function String$format(format, args) {...}
In the release version of the library we have:
Sys._Debug.prototype = {
assert: function(c, a, b) {
...
}
and:
String.format = function() {...}
In the release version, we have methods that are anonymous functions. This means that within a debugger stack trace the method name will read JScript anonymous function. This is not very useful for debugging purposes, is it?
Call Stack showing anonymous functions
However, the debug version of the library uses the dollar-syntax to provide alias names for our functions: String$format for String.format and Sys$Debug$assert for Sys.Debug.assert. When using the debug version of the file, the stack trace would look like:
Call Stack showing named functions
We can still notice some anonymous functions as they are the result of creating callback or delegate functions. The example shows two different ways of coding:
Another interesting feature that has not been documented in the Microsoft AJAX Library documentation is that of parameters validation.
Type safety is one of the typical problems when it comes to using JavaScript. Although the dynamic type features are really useful, sometimes we might really want to make sure that a parameter or object is of a certain type. To check the data type of an object, you can try converting the object to the desired type, or using the methods defined by Type. Fortunately the Microsoft AJAX Library has a function that does the dirty work for us: Function._validateParams(). The class diagram in figure below shows the _validateParameter() and _validateParams() methods of the Function class.
The Function class
The Function._validateParams() function, even if it is declared as private (by convention, using the leading underscore), can be used by our scripts as it is used throughout the debug version of the Microsoft AJAX Library. Here’s an example of using this function:
function Sys$_Debug$fail(message) {
/// <param name="message" type="String" mayBeNull="true"></param>
var e = Function._validateParams(arguments,
[ {name: "message", type: String, mayBeNull: true} ]);
if (e) throw e;
This shows how the parameter for the fail() function is validated as a String. We can also see the additional code comments inside the function, which are meant to be used by the IntelliSense feature in Visual Studio “Orcas” to check for the correctness of the parameter types.
While the first parameter of _validateParams() represents an array of parameters to be checked, the second parameter is an array of JSON objects describing the validation rules for the array of parameters. Each JSON object contains a validation rule for a parameter. The JSON object is a dictionary of keys and values. The list of keys that can be used is described in the table that follows.
Key | Description |
name | The name of the parameter |
type | The allowed type for this parameter (ex: String, Array, Function, Sys.Component, etc.) |
mayBeNull | Boolean value indicating whether this parameter can be passed as null or not |
domElement | Boolean value indicating whether this parameter is a DOM element or not |
integer | Boolean value indicating whether this parameter should have an integer value or not |
optional | Boolean value indicating whether this parameter is optional or not |
parameterArray | Boolean value indicating whether this parameter should be an Array or not |
elementType | The allowed type for each element of an array (type must be Array) |
elementMayBeNull | Boolean value indicating whether an array element could have null or not (type must be Array) |
elementDomElement | Boolean value indicating whether each element of an array is a DOM element (type must be Array) |
elementInteger | Boolean value indicating whether each element of an array should have an integer value (type must be Array) |
The function returns an error message if the parameters don’t validate and the error is typically thrown like this:
if (e) throw e;
This exception could be caught and the appropriate measures taken programmatically. If the exception is not caught, the error will pop up in the debugging console of the browser.