Revealing ColdFusion exceptions hidden by try/catch

This post is more than 2 years old.

Yesterday Mike Henke asked an interesting question on Twitter. (And I should thank him as this is the second time now one of his tweets has led to an interesting discussion.) He wished there was a way to make a try/catch be disabled when testing. Obviously you wouldn't do this in production, but I think most folks could imagine needing to temporarily disable a try/catch so that you can see full details of an error. I decided to take a quick look into this and found something I thought was interesting.

First off - if you are willing to edit code, then you could just remove the try/catch. Another quick hack would be to use a conditional rethrow as in the pseudo-code below:

<cftry> <cf_dosomethingnaughty> <cfcatch> <cfif is notProduction> <cfrethrow> </cfif> <p>I'm so sorry you got an error. I really do care. Really.</p> </cfcatch> </cftry>

That's a manual approach and would work, but I had a hunch about an alternative that could possibly work as well. I remembered that exceptions show up when ColdFusion debugging is turned on. So I whipped up a CFM with an error in it wrapped in try/catch then loaded it. As expected, my error was hidden in the main display, and down in my debug area I could clearly see the exception:

So that may be good enough. But there isn't a lot of detail in there. I opened up the debug template and looked at how we gather the exception info:

<cfquery dbType="query" name="cfdebug_ex" debug="false"> SELECT * FROM qEvents WHERE type = 'Exception' </cfquery>

For the hell of it, I quickly added a cfdump and looked at the data. Guess what? The entire stack trace is there. The debug template simply doesn't use it. To be fair, they are kinda big, but I went ahead and modified the display code:

<!--- Exceptions ---> <cfif bFoundExceptions> <cftry> <cfoutput> <p class="cfdebug"><hr/><b class="cfdebuglge"><a name="cfdebug_exceptions">Exceptions</a></b></p> <cfloop query="cfdebug_ex"> <div class="cfdebug">#TimeFormat(cfdebug_ex.timestamp, "HH:mm:ss.SSS")# - #cfdebug_ex.name# <cfif FindNoCase("Exception", cfdebug_ex.name) EQ 0>Exception</cfif> - in #encodeForErrorSmart(cfdebug_ex.template)# : line #encodeForErrorSmart(cfdebug_ex.line)#</div> <cfif IsDefined("cfdebug_ex.message") AND Len(Trim(cfdebug_ex.message)) GT 0> <pre> #encodeForErrorSmart(cfdebug_ex.message)# </pre> <cfdump var="#cfdebug_ex.stacktrace#"> </cfif> </cfloop> </cfoutput> <cfcatch type="Any"> <!--- Error reporting an exception event entry. ---> </cfcatch> </cftry> </cfif>

Just to be sure it's clear - my modification is the cfdump. Here's a screen shot:

What do folks think about this approach? I know I've said it many times before, but do not forget that both the debug and exception templates are open source. You can hack them up - as I and others have done over the years. If you want to try this mod, just save the attached file to your WEB-INF/debug folder and select the filename "ray" in your ColdFusion Administrator settings.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Terry Sampson posted on 3/29/2012 at 6:24 PM

I have been looking for something like this forever. I like your approach, but it might be something I can use.
I just removed it in deve and put it back in producttion.

Good one.

I will try this tomorrow since I am working on an update to a web app right now.

Comment 2 by Matt Gutting posted on 3/29/2012 at 8:00 PM

Nice. I'd been using something like "if not isProduction then cfdump var="#cfcatch#". I like this better!

Comment 3 by Terry Sampson posted on 3/29/2012 at 8:07 PM

I'd been using a cfinclude for my cfcatch that contains my error code, but I like this better too.

Comment 4 by Jake Munson posted on 4/3/2012 at 12:56 AM

My only beef with this approach is that editing system CF files means that you have to remember to do it with every upgrade. Not a show stopper, but it is just one more thing you might forget when moving to a new box or upgrading.

Comment 5 by Raymond Camden posted on 4/3/2012 at 1:24 AM

Technically you can make a copy of default.cfm - that's what I did. ;)