DP_Debug

The DP_Debug utility script extends JavaScript with (we think) useful debugging methods. The following methods are made available:

  • dump(): Converts JavaScript objects (their properties, values and relationships) to an HTML representation and displays this in the console for review. It supports objects with circular/recursive references. It’s similar to the insanely useful CFDUMP tag in ColdFusion.
  • dumpCookies(): A convenience method which dumps all available browser cookies to the console.
  • dumpQueryString(): A convenience method which dumps all available query-string names and values to the console.
  • logger(): A method for logging messages to the console using either custom or predefined types. logInfo(), logWarning() and logError() are all shortcut methods for logging specific types of messages easily.
  • timer(): A method for timing blocks of code.
  • getType(): Provides more advanced Object type-recognition than the native “typeof” operator.

The extension is self-contained and present an extremely small footprint. Only a single global object, “DP_Debug”, is created.

This component requires a JavaScript (ECMAScript) 1.3 (or better) environment and has been tested successfully on Internet Explorer 6+, Firefox 1+ and Opera 9+.

Download

The component is available from GitHub:

All downloads and code are covered by our Source Code Policy.

Usage

The library consists of a single JavaScript file with a .JS extension.

Importing the Library

The library must be imported before it is used. To import the library use the <script> tag. For example:

<script type="text/javascript" src="DP_Debug.js"></script>

Your path may vary depending on the location of the script on your server.

Accessing Library Functions

The library functions are implemented as methods of the DP_Debug object. Thus (if the library has been imported) the following are all legal:

		// Start a Timer
	DP_Debug.timer();
		// Instantiate and dump an Object
	var MyObject = {property1: "value1", property2: "value2"};
	DP_Debug.dump(MyObject);
		// Log a message
	DP_Debug.logger("My Message", "Info");
		// End the Timer
	DP_Debug.timer();
	

Using dump()

dump() displays it’s information in the dump console panel. Dump information is listed from oldest to newest (recent dumps will be at the bottom of the list). You can clear the dump panel using the “clear” link above it.

dump() Log Entries

Running dump automatically generates a related log entry. This entry (color-coded gray) lists the ID number of the dump, the developer supplied label (if any) and the duration of the dump operation. This allows the developer to gain some insight as to how much time dump() operations are taking in comparison to the core application.

dump() with System Objects

While dump() can, in principle, handle most built-in JavaScript objects such as “document” and “window” full recursive dumps of these objects will produce thousands upon thousands of items: in most cases attempting to dump the entire object will hang the script engine.

To explore these objects use the MaxRecurseLevel attribute to limit your response set. Informal testing has shown that for base system objects (for example “document”) two or three levels can normally be dumped. A powerful machine may be able to do five or even six levels before the browser throws a “slow script warning” or crashes with a stack overflow. Experiment to see how many levels your browser and machine can safely handle.

Dumping system objects can be very useful however. Using dump(), for example, you can easily get a list of a style properties and their current values for any element. You can also dump many of the built in arrays such as “document.images”, “document.links” and so on.

Understanding dump() Output

Every effort has been made to make dump output understandable and usable. The output for each dump call starts with a solid blue title bar with a generated dump ID number (and an optional developer label). Each data element displays the name of the element on the left, the data type and (for complex objects) an Object ID on the right. The actual data corresponding to the element is indented below. You may click on the name of an element to hide the associated data (the name will now be italicized). Click on the name again to reveal the hidden data.

Complex objects (objects and arrays) are presented in blue frames to indicate their status as groups of elements. They are given, when first encountered, a unique ID value which is displayed above the data. If the same complex object is encountered again a reference to its ID will be displayed (and, in Internet Explorer, this reference is linked to the original display) but the object data will not be displayed again. This prevents endless loops when displaying objects with circular references.

There are several informational system messages which may be displayed in the data area of an element. These will be displayed using a monotype font in parenthesis. The possible messages and their meanings are:

  • ( Previously Displayed ): This message is displayed when a complex object has already been displayed in the current dump. Refer to the ID number above the message to locate the object referenced.
  • ( Maximum Recursion Depth Reached ): When using the MaxRecurseLevel argument any objects which are not detailed due to the depth restriction will display this message instead.
  • ( null ): The value of the element is null.
  • ( Empty String ): The element is a string, but has no content (the element’s length is zero).
  • ( Undefined Entity ): The element contains the undefined value (this may happen, for example, with sparse arrays).
  • ( Object is not Enumerable ): Although it reports itself as an object the element causes an error when attempts are made to examine its properties. This generally only happens with system objects.
  • ( Entity is not Enumerable ): The element is a property of an object but neither its type or value can be examined (when attempting to do so dump encounters an error). This generally only happens with system objects.

Using logger()

logger() displays its information in the log console panel. Log information is listed from oldest to newest (recent entries will be at the bottom of the list). You can clear the dump panel using the “clear” link above it.

Understanding logger() Entries

Log entries are presented with three pieces of information:

  • Type: Type is the color-coded type of the entry. The following types are supported:
    • Info: Color-coded Green. This type can be specified manually using the logger() method or automatically using logInfo(). method
    • Warning: Color-coded Yellow. This type can be specified manually using the logger() method or automatically using the logWarning() method.
    • Error: Color-coded Red. This type can be specified manually using the logger() method or automatically using the logError() method.
    • Timer: Color-coded Blue. This type of entry is automatically generated by the timer() method.
    • Dump: Color-coded Gray. This type of entry is automatically generated by the dump() method.
    • Custom: Color-coded White. This entry type covers all custom log type values entered by the user.
  • Time: The time of the log entry using a 24-hour clock (with milliseconds).
  • Entry: The text message of the log entry.

Using timer()

timer() displays information in the log console panel using a log entry type of “Timer” (color-coded blue).

To complete a timer operation you must call timer() with the selected name twice: once to start the timer and once to end it and display the results. Both calls will generate log entries and the duration of the timer, in milliseconds, will be displayed on the second entry.

timer() accepts a “Name” attribute used to label the timer. Because of this multiple timers can be configured simultaneously and can overlap one another.

Security Issues

Internet Explorer on Windows XP SP 2 or in Windows 2003 locks down the local machine such that no client-side script can run. This will break DP_Debug completely if you attempt to run it locally. There are (at least) two solutions to this:

  • Don’t run DP_Debug locally. Running it from a server (which places the files in the “Internet” security zone) allows it to run.
  • In Internet Explorer go to the “Tools” menu and choose “Internet Options”. Choose the “Advanced” tab of the dialog and scroll to the last group of options called “Security”. Check the box that says “Allow active content to run in files on My Computer”. Note that this will, of course, allow other active content besides DP_Debug to run.

DP_Debug attempts to open a pop-up window via Script to display its results. Some pop-up blockers may prevent this from happening. Disable your pop-up blocker(s) for the web site you are testing if this is the case.

Integrating DP_Debug into Applications

DP_Debug can be used as needed (added, used, then removed) or integrated into the application. The latter option may be a bit more work but can save time in the long run as you can easily enable or disable complex debugging calls.

The Enabled Flag

The Enabled flag is simply a boolean flag, DP_Debug.Enabled, which defaults to “false”. It’s controlled programmtically by the DP_Debug.enabled() and DP_Debug.disabled() methods which set the value to “true” and “false” respectively. The DP_Debug.isEnabled() method will return the value of the flag.

It’s important to understand that the flag actually has no affect on the processing of the various DP_Debug methods. If you call DP_Debug.dump() you will always get a dum regardless of the value of the flag. The flag is only useful if it’s checked explicitly.

The following code demonstrates setting the enabled flag and doing a debug log entry based on the value.

		// Enable the Flag
	DP_Debug.enable();
		// Check the Flag, set a log entry if true
	if ( DP_Debug.isEnable() ) {
		DP_Debug.logger("Application Initialized", "MyApp");
	};
	DP_Debug.logger("Application Information", "MyApp");
	

The first line, which sets the enabled flag to “true”, can be commented out or removed to prevent debugging information from being displayed. Note, importantly, that the second call to logger will ALWAYS function, regardless of the enabled flag value.

Integration Suggestions

Although the above code works there are several potential issues that are worth talking about.

Firstly the code above will (perhaps obviously) fail if the DP_Debug library hasn’t been loaded. To save download time most authors will probably not include the debugging library in production applications. Unfortunately there doesn’t seem to be a decent method to determine whether an object/method exists across supported browsers. In the end the easiest, cleanest and (perhaps) best way to do this is to wrap your debugging declarations in a try/catch block like so:

	try {
		if ( DP_Debug.isEnable() ) {
			DP_Debug.logger("Application Initialized", "MyApp");
		};
	} catch(e) {};
	

This code will function whether or not the DP_Debug library has been loaded and should work in all browsers that support DP_Debug. The try/catch also has the benefit of trapping any other errors which may slip through (since debugging code is rarely tested as well and mainline code).

Being able to enable or disable debugging information on demand can be very useful. One way to do this is via Query String variables such as “http://www.myapp.com/index.htm?debugmode=true”. You can access Query String values easily using DP_QueryString. Using this library you can check for the query string argument in the example and set enabled flag like so:

	if ( DP_QueryString.get("debugmode")[0] ) {
		DP_Debug.enable();
	} else {
		DP_Debug.disable();
	};
	

Methods

These methods are created as methods of the “DP_Debug” object:

Note that in method/function signatures a pipe (“|”) indicates “OR” while arguments in square brackets are optional.

DP_Debug.dump()

Dumps an HTML representation of the passed JavaScript data to the DP_Debug console. Also results in a log entry of type “Dump” to be created.

Method Signature

DP_Debug.dump(Ob, [Label], [ShowFunctions], [MaxRecurseLevel])

Arguments

This method has four arguments:

  • Ob: Object, required. The object which you’d like to dump. Note that this can be nearly any value (since nearly all values are accessible objects).
  • Label: String, optional (defaults to empty string). An arbitrary developer label to be displayed with the dump output. For example “CurrentRecord” or “Account Before Loop”. This can assist the developer in determining which output belongs to which call of the method in a complex process.
  • ShowFunctions: Boolean, optional (defaults to false). If set to true user-defined functions, in addition to object properties will be displayed as part of the dump output.
  • MaxRecurseLevel: Numeric, optional (defaults to -1 which indicates no limit). This argument determines how deeply an object should be explored. Use this argument to limit your output when working with very large, “deep” objects.

Return

DP_Debug. dump() returns a reference to the object instance.

DP_Debug.dumpCookies()

A convenience method which collects currently accessible browser cookies and dumps them to the dump console. Note that only cookies accessible to JavaScript (based upon the browser security model) can be identified.

Method Signature

DP_Debug.dumpCookies()

Arguments

This method has no arguments.

Return

DP_Debug. Returns a reference to a generated object which represents accessible browser cookies.

DP_Debug.dumpQueryString()

A convenience method which collects currently accessible Query String (“Command Line”) name=value pairs and dumps them to the dump console.

Method Signature

DP_Debug.dumpQueryString()

Arguments

This method has no arguments.

Return

DP_Debug. Returns a reference to a generated object which represents accessible Query String values.

DP_Debug.getType()

Gets the type of the current DP_Debug. This function will return distinct object types such as “array”, “string” and “date” where the native typeof operator would return a value of “object”.

Method Signature

DP_Debug.getType(CurOb)

Arguments

This method has one argument:

  • CurOb: Object, required. Any JavaScript DP_Debug.

Return

String. A label indicating the type of the DP_Debug. This can be one of the following values:

  • null
  • array
  • object
  • function
  • date
  • number
  • string
  • boolean
  • undefined
  • unknown

DP_Debug.logger()

Creates a log entry in the log console.

Method Signature

DP_Debug.logger(Message, Type)

Arguments

This method has two arguments:

  • Message: String, required. The message to be displayed in the log entry.
  • Type: String, required. The type of the log entry. Can be either one of the pre-defined types (“Info”, “Warning” or “Error”) or a custom type. (Note that the types “Dump” and “Timer” are reserved.)

Return

Void.

DP_Debug.logError()

Creates a log entry of type “Error” in the log console.

Method Signature

DP_Debug.logError(Message)

Arguments

This method has one argument:

  • Message: String, required. The message to be displayed in the log entry.

Return

Void.

DP_Debug.logInfo()

Creates a log entry of type “Info” in the log console.

Method Signature

DP_Debug.logInfo(Message)

Arguments

This method has one argument:

  • Message: String, required. The message to be displayed in the log entry.

Return

Void.

DP_Debug.logWarning()

Creates a log entry of type “Warning” in the log console.

Method Signature

DP_Debug.logWarning(Message)

Arguments

This method has one argument:

  • Message: String, required. The message to be displayed in the log entry.

Return

Void.

DP_Debug.timer()

Either creates and starts a timer with the specified name or (if the timer already exists) stops the timer and logs the results to the log console.

Method Signature

DP_Debug.timer([Name])

Arguments

This method has one argument:

  • Name: String, optional (defaults to “timer”). The name of the timer.

Return

Void.

DP_Debug.enable()

Sets the “enabled” flag to true. Use the isEnabled() method to examine the flag.

Method Signature

DP_Debug.enable()

Arguments

This method has no arguments.

Return

Void.

DP_Debug.disable()

Sets the “enabled” flag to false. Use the isEnabled() method to examine the flag.

Method Signature

DP_Debug.disable()

Arguments

This method has no arguments.

Return

Void.

DP_Debug.isEnabled()

Returns the current value of the “enabled” flag.

Method Signature

DP_Debug.isEnabled()

Arguments

This method has no arguments.

Return

Void.

Examples

What follows are several examples of calling debugging methods with various objects. You must have JavaScript enabled to view the examples and the examples will open in a new window.

Note that the debug console will add any new output to the bottom of the console: make sure that you’re looking at the right output (you can also close the window or use the provided “clear” controls to empty the consoles if this becomes confusing). The debug window will not appropriate focus so you may have to resurface it yourself if it falls behind the main window.

Revision History

June 8, 2013

  • Initial GITHUB release.

October 25, 2006

  • Added the enable(), disable() and isEnabled() methods to make integration/optional debugging simpler.

October 19, 2006

  • Fixed a bug which prevented the display of “null” properties in some cases.

September 25, 2006

Sorry for the major changes less than two days from release… It just struck me that all the reasons for placing the methods in the base JavaScript Object have been eliminated.

  • Moved the functions from the Object to a new global object, “DP_Debug”.
  • Removed the prefix “dp” from all methods (it’s no longer needed for identification with the new global object).
  • Changed the name of the “log” method to “logger” (“log” is reserved).
  • Fixed a bug with the getType() method.

September 22, 2006

  • Add the ability to filter the log console to only display specific types of messages.

September 20, 2006

This version is a near-complete rewrite of DP_Debug essentially compromising a “version 2.0”. Many new features have been added.

  • Added the logger() method and attendant shortcut methods (logInfo(), logWarning() and logError()).
  • Added the dumpCookies() and dumpQueryString() methods.
  • Added the timer() method.
  • Improved the dump method with better reference handling, labeling and several small performance and visual tweaks. In addition dump automatically creates a log entry containing the duration of the dump process.
  • Added a “Quick Reference” to the console which gives a quick synopsis of all available methods.
  • Greatly improved the console HTML and pop-up window handling.
  • Opera 9.x is now supported.
  • Removed the dpDebugInstances() method. It was never used and made documentation very difficult.

September 3, 2005

  • Added the ability to toggle the display of any element data by clicking on the element label.
  • Add the “MaxRecurseLevel” parameter to dump. This, along with other refinements, allows you to dump at least portions of large built in objects like “document” without hanging the scripting engine.
  • Added local links to previously displayed objects. Currently only Internet Explorer supports these links however.
  • Added error checking the getType() which allows it to return even when faced with oddball built-in objects like “external”.

August 24, 2005

  • Redesigned the methods as static methods and added the dpDebugInstances() function to interactively manage the impact to DP_Debug.prototype. Thanks to Martin Bialasinski on comp.lang.javascript for inspiring this change.

August 23, 2005

  • Streamlined the constructor identification used by getType(). This does not change processing. Thanks to BigMoosie on the webdevloper.com JavaSCript forum for the suggestion.
  • Prevented the dump from explicitly flagging out-of-range numbers. It will now output JavaScript’s standard identifiers for such things. Thanks again to BigMoosie on the webdevloper.com JavaSCript forum for the suggestion.

August 22, 2005

  • Initial Release.