Java Platform, Enterprise Edition

Java EE Journal

Subscribe to Java EE Journal: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get Java EE Journal: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn

J2EE Journal Authors: Zakia Bouachraoui, Douglas Lyon, Stackify Blog, APM Blog, Sumith Kumar Puri

Related Topics: ColdFusion on Ulitzer, Java EE Journal

CFDJ: Article

Macromedia ColdFusion Debugging - Don't Forget Your Bug Spray!

'Sorry about that Adam, we'll have to take a deeper look at it. Uh-huh. Yeah.

"Sorry about that Adam, we'll have to take a deeper look at it. Uh-huh. Yeah. No, I totally understand. Okay then, I'll give you a call if I still can't replicate the problem."

Many of you recognize this phone call: the client has an issue and now you have to figure out why. I usually find issues like this much more frustrating than a cold hard error. At least with an error you get something concrete, you get facts about the problem. But these types of bugs, often problems with the application's logic, are the ones that sneak through to the client and are difficult to track down. I call this kind of bug No-see-ums, named after the teeny tiny mosquitoes commonly found in the Everglades.

Luckily for me, ColdFusion provides great tools for tracking down bugs like these. So armed with a fly swatter (error handling) and a can of Off (debugging), away I work at tracking down Adam's problem.

I liken debugging to Off bug spray. Debugging tools will help you keep the bugs away, but they can still get through and bite you. ColdFusion provides two great ways to debug applications. The first is code based, through the use of tags like <cfdump>, <cftrace>, and <cftimer> and the function isDebugMode(); the second is through site-wide debugging.

Any developer who uses ColdFusion and another language no doubt misses the <cfdump> functionality in their other development environment. <cfdump> provides a color-coded graphical representation of complex objects, as well as the standard output of simple ones. This includes red components, blue structures, green arrays, purple queries, orange functions, gray XML, and black WDDX packets. <cftrace> displays and logs debugging data about an application at runtime. It can track logic flow, variable values, and execution time. <cftrace> can display its output at the end of the request or in the debugging section at the end of the request, or in Dreamweaver MX, in the Server Debug tab of the Results window. ColdFusion also logs all <cftrace> output to the file logs\cftrace.log, in the ColdFusion installation directory. <cftimer> calculates execution time for any chunk code and displays it along with any output produced by said code. isDebugMode() is a simple function that returns a Boolean expression indicating whether site-wide debugging is enabled or not.

ColdFusion makes it easy for developers to turn on site-wide debugging information. When site-wide debugging is enabled, pertinent information is appended to the end of every request, allowing the developer to see much of what is going on under the surface. What information the debugger will show can be set in the ColdFusion Administrator.

Even though ColdFusion debugging gives developers an enormous head start on creating bug-free applications, it's only a good defense. Many times you will still need to anticipate and take action to accurately eliminate bugs.

Ray Romano
Ray Romano has said, "I don't care how brave you are; you don't just rush in and kill an unknown bug. You got to figure it out first. I don't know if it has the gift of flight. What if it's a flyer? Then you got to close up hatches and stuff."

Bugs that generate a ColdFusion error are actually easy to identify, you just have to know what to look for.

When there is a ColdFusion error, it provides information about the error in an easy-to-access structure. The structure contains many keys, a lot of which are optional. (So be sure to check for their existence before referencing them.) The most recognizable key in the structure is the message key. It contains the default error message, usually shown in bold on a default error screen. If no error message is available, the key will contain an empty string. The detail key contains a detailed HTML message from ColdFusion and will help you determine which tag caused the error. ErrorCode will most likely contain an empty string, but you can supply a value for it through the errorCode attribute of <cfthrow> tags. ExtendedInfo is similar to ErrorCode in that it's usually an empty string. The exception to this rule is when the Type key, which contains the error's type, is the string application. Since ColdFusion is running Java under the hood, all errors are really Java errors. When an error is thrown, the Java Virtual Machine reports a servlet exception, which is stored in the RootCause key.

TagContext is one of the most robust error keys. It contains a stack of structures, where each element in the stack represents an open tag, and the structure in that element contains more detailed information about that tag. This structure will contain an ID key that represents the open tag. If the open tag is a custom tag, the value will read cfmodule, and if it is <cfscript>, it will read "??". The structure will also tell you which line of code the open tag can be found on, the Line key, and in which ColdFusion file it is in, the Template key. The raw Java stack trace for the error can be found in the Raw_Trace key. The structure also contains two peculiar keys. The first is Column, which is always 0, but is retained for compatibility with older versions of ColdFusion. The second is Type, which is always a string equal to CFML.

Other keys in the error structure show up depending on the type of error that has been thrown. For database errors, an additional five keys may be present. NativeErrorCode contains an error code submitted by the database driver. Because of the varying drivers that ColdFusion supports, the values for this will vary. However, if the driver does not submit a value, the default is -1, and if the query is a query of queries, the value will be 0. SQLState is very similar to NativeErrorCode in that it is derived from the database driver. It is code given to assist in the diagnosis of failing database operations, and its default is also -1. Sql contains the parsed SQL statement that was sent to the DBMS, while the string representation of the DBMS error is stored in the QuerryError key. If <cfqueryparam> tags were used in the query, the Where key will contain the name-value pair of each.

Another special key that may appear is the ErrNumber key, only found for expression exceptions. It represents an internal expression error number. Missing include errors add a MissingFileName key that gives the name of the missing file. Locking errors add an additional two keys: LockName and LockOperation. LockName contains the name of the affected lock. If the affected lock is unnamed, the value will be anonymous. LockOperation will contain the operation that failed or unknown.

Now that we know what we are dealing with (read "All hatches closed"), we can get offensive.

The Fly Swatter
ColdFusion provides a handful of mechanisms for handling errors. There are tags in the form of <cferror>, <cftry>, <cfcatch>, <cfthrow>, and <cfrethrow>; site-wide management in the ColdFusion Administrator; and (new to CFMX 7.0) there is an onError() function in the Application.cfc. Each method of error handling has its own strengths and weaknesses, but a combination of the methods provides the most complete solution.

More Stories By Nik Molnar

Nik Molnar is a ColdFusion/Flex developer with over seven years experience. He has led teams through the development of enterprise applications for the mortgage, sports ticketing, and stock industries. He is an amateur Iron Chef and posts regularly at his blog: He lives with his wife Katy and his dog Jacques in Orlando, Florida.

Comments (2)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.