Fixing problems within your code can sometimes be very difficult. If the problem you are experiencing is an error, then the chances are it is pretty easy to fix as you already know the file and line number of the issue. If the issue you are trying to fix is that a piece of functionality is not acting as you expected, then the problem is a bit harder to resolve. There is no sure way to find these problems and fix them, but there are a few debugging methods that can often help you find the problem area.
When trying to debug a problem within your application, it can sometimes be a very easy task or sometimes it can be a very arduous task. When an error is thrown, you often know the file and line number of the problem and you can fix it very easily. Sometimes the problem is that the application is not doing what you expected it to do and often this is a much harder problem to resolve. During these situations, the more information you have, the better. This is where the Request Debugging Output can help you.
On every page request, there is a lot of information that ColdFusion has about the request that you do not usually see. By default, this output is turned off,as it is not recommended that this be turned on in a production environment as it can slow down the page load times. If it were enabled on a production server, the information would not be displayed to everyone, as it is only shown to approved IP addresses. To turn on the Request Debugging information on your local server, log in to the ColdFusion Administrator and go to Debugging & Logging > Debug Output Settings; select the Enable Request Debugging Output checkbox. Once you click save, you should now see the debugging information at the bottom of every ColdFusion page that runs on your server. If you go to a ColdFusion page and you do not see that information, log back in to the ColdFusion Administrator and go to Debugging & Logging > Debugging IP Addresses. On this screen you will see a list of all IP addresses that are able to see the debugging information. Click on the Add Current button. This will add your local IP address to the list (127.0.0.1 and 0:0: 0:0: 0:0: 0:1 are added automatically) and you should now see debugging information on every ColdFusion request.
The debugging information offers a lot of request information that can be very useful when debugging an issue. The output is comprised of the following sections:
Using this information, you can often find where the problem might be occurring.
The cftrace tag allows you to record the state of variables within your application at a specific time. It tracks the run-time logic flow, variables values, and execution time. The cftrace tag can be placed anywhere inside your code any number of times. You can specify a variable that you wish to trace, some text to associate with the trace, if you wish the trace to be inline or not, and if you wish it to stop the processing of the page or not. The cftrace tag has two output options: inline or not inline. If the inline attribute is set to true, then the trace information will be displayed at the end of the page request as well as within the request debugging output. If the attribute is set to false, then the information will only be displayed in the debugging output. In addition to the information being displayed on the page, the same information is stored in the cftrace.log file in the ColdFusion Administrator.
The cftrace tag has an abort option, which, when set to yes, will halt the page processing right after the tag. If this is set to false, the page will continue to process. Often, the best way to use the cftrace tag is to not set the abort option to true, but to let the page run. Placing multiple cftrace tags within the site will allow you to see the value of a variable at different stages of the request cycle. This will often allow you to track down where unexpected anomalies might occur.
Here is an example of the cftrace tag. In this example we are tracing a variable called today:
<cftrace var = "today" text = "I am expecting this to be Friday" type = "information">
Here is the output we received when the tag was run:
[23:26: 26.012 /Users/simon/Sites/learncfinaweek/frontend/views/main/default.cfm @ line: 8] [33 ms (1st trace)] - [today = Sunday] I am expecting this to be Friday
As you can see, the value of Today is Sunday. As you can tell from the text added, we expected the value to be Friday; these values do not match, so we know that we must be close to our problem.
Another method to help debugging a problem is to use the cfdump tag. The cfdump tag will output any variable, even variables that are not a simple value. Dumping variables allows you to see the current state of the variable and any values it might hold. If the variable is more complex, such as an object or ORM entity, then the cfdump tag will show you all available properties and methods for that object. In its simplest use case, the cfdump tag is provided a variable to be dumped. For simple variables, this is fine, but for variables that are more complex, such as ORM Entities, this can cause for a lot of information to be output and possibly cause a Java Heap error. For more complex variables, it is often necessary to use some additional attributes. The top attribute allows you to specify a number which represents the depth that you wish the dump to go. For example, if you specified a top value of 3 and the variable was a query, only the top 3 rows would be output.
When cfdump is called, it outputs the provided variable and the page continues to process. In some scenarios, it is necessary for you to stop the page process right after the dump. If you are writing the cfdump tag, then you can simply add the word abort to your attribute list, and the page will stop processing after the tag.
In situations where you have multiple cfdumps being called, it might get confusing which output relates to which tag in your files. For that purpose, there is a label attribute that allows you to specify some text which will be displayed with your dump.
Here is an example of a cfdump that dumps the session scope, only going 3 levels deep, and aborting once it has run:
<cfdump var="#session#" label="I am the session scope" top="3" abort>
And here is the script alternative:
<cfscript> writedump(var="#session#" top="3" label="I am the session scope" abort=true); </cfscript>
One feature of the cfdump tag that can be very useful is its ability to write to a file rather than displaying to a page. This allows the page to be executed uninterrupted, but still allow you to get the data you need. To write to a file, just simply provide a file path to the output attribute:
<cfscript> dumpLocation = expandPath("writeDumpResults.html"); writedump(var=someVar format="html" output="dumpLocation" label="I am dumping to a file" abort=true); </cfscript>