Revealing ColdFusion exceptions hidden by try/catch

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 developer advocate looking for his next gig. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

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

Comments