This morning I was working on some code where I wanted to capture an error in side a cftry/cfcatch block and rethrow the message, but I wanted to modify the cfcatch.message key to include more detail without losing the stack trace. I could have just used the <cfthrow /> tag and used the type, message and detail attributes but this would have caused me to lose the stack trace—which I needed.
Idealistically, I could have just modified the "message" key in the cfcatch variable, but the problem is the ColdFusion cfcatch variable is not really a struct—it looks like one—but it's actually an Java exception. Because it's not really a struct, it's not possible to just edit key values—making the cfcatch variable essentially read-only.
This got me looking into a method were I could rethrow the original stack trace, but customize the "message" key. After a few minutes playing around the java.lang.Exception object, I came up with the following:
<cffunction name="rethrowMessage" access="public" returntype="void" output="false" hint="Rethrow a CFCATCH error, but allows customizing the message key"> <cfargument name="cfcatch" type="any" required="true" /> <cfargument name="message" type="string" required="false" /> <cfset var exception = "" /> <cfif not structKeyExists(arguments, "message")> <cfset arguments.message = arguments.cfcatch.message /> </cfif> <cfset exception = createObject("java", "java.lang.Exception").init(arguments.message) /> <cfset exception.initCause(arguments.cfcatch.getCause()) /> <cfset exception.setStackTrace(arguments.cfcatch.getStackTrace()) /> <cfthrow object="#exception#" /> </cffunction>
Using this UDF, I can now do something like:
<cfscript> // connect and authenticate try { store.connect(variables.instance.server, variables.instance.username, variables.instance.password); } catch(Any e) { // throw original message, but append the username to the message rethrowMessage(cfcatch=e, message=e.Message & " [#variables.instance.username#]"); } </cfscript>
This allows me to throw the original Java error that occurs when connecting to a JavaMail Store occurs, but modify the message to include the mailbox I'm trying to connect to which is helpful in debugging the root cause.
3 Comments
Comments for this entry have been disabled.