<cfparam name="cfcatch.detail" default="" />That would be way too easy. I found a couple places that suggested using duplicate() to make it act like a struct. I tried that too, and you still can't do a cfparam on it. The key simply won't exist.
After much googling, I came across this post by Isaac Dealey. So using that idea, I created the following function:
<cffunction name="structifyCatch" returntype="struct">then to implement it, you call the following:
<cfargument name="catch" type="any" required="true"/>
<cfset var err = structnew() />
<cfset structappend(err,arguments.catch,true) />
<cfreturn err />
</cffunction>
<cftry>Hopefully this will save you a little bit of angst.
... some code ...
<cfcatch>
<cfset cfcatch = structifyCatch(cfcatch) />
<cfparam name="cfcatch.message" default=""/>
<cfparam name="cfcatch.detail" default=""/>
<cflog text="There was an error in somecode().
Message: #cfcatch.message# Detail: #cfcatch.Detail#"
application="yes">
</cfcatch>
</cftry>
There are some interesting behaviors documented here too:
cfcatch was born a struct, then it wasn’t but now it’s back
Blessings,
Terry
5 comments:
I wonder if StructCopy() would be work when Duplicate() didn't. Duplicate() might be *too good* at copying the underlying object, while StructCopy() might work based on keys. I haven't testet this.
I tried structcopy() first to no avail. In fact it failed because it doesn't think it's a struct. The message basically said that you can't do a struct copy on this type of object. I wish cfcatch wasn't even called a struct. It leads to all sorts of false hopes. Either that or make it a true struct.
Can you post some code that reproduces this symptom of keys missing from the exception struct? I've never come across this.
--
Adam
While it does seem wrong if the detail property (or any of the others on page 72 of the CFML Reference)aren't available, why couldn't you use StructKeyExist(cfcatch,"detail") as part of a conditional statement?
@Adam .. just a quick example with the "SQL" key. This will only be available if the catch type is database. There are times where you are catching any catch type and would like to spit out sql if its available.
<cftry>
<cfset x = a />
<cfcatch>
<cfoutput>
#cfcatch.message#<br />
#cfcatch.sql#
</cfoutput>
</cfcatch>
</cftry>
@Jason .. "Why not just throw in some conditional logic?" Absolutely you could. I guess this was just out of principle, or maybe stubborness. I would much rather do:
<cffunction name="someFunction" returntype="string">
<cftry>
... do some code here ...
<cfcatch>
<cfset cfcatch = structifyCatch(cfcatch)>
<cfparam name="cfcatch.detail" default=""/>
<cfparam name="cfcatch.message" default=""/>
<cflog application="true" text="Message: #cfcatch.message# Detail: #cfcatch.detail#"/>
</cfcatch>
</cftry>
<cfreturn ''/>
</cffunction>
than I would this:
<cffunction name="someFunction" returntype="string">
<cfset var _message = ''/>
<cfset var _detail = ""/>
<cftry>
... do some code here ...
<cfcatch>
<cfif structkeyexists(cfcatch,'message')>
<cfset _message = cfcatch.message />
</cfif>
<cfif structkeyexists(cfcatch,'detail')>
<cfset _detail = cfcatch.detail />
</cfif>
<cflog application="true" text="Message: #_message# Detail: #_detail#"/>
</cfcatch>
</cftry>
<cfreturn ''/>
</cffunction>
In one particular place I was doing a lot of trapping and logging with try/catch and just got sick of having to throw in extra conditional logic in when "in theory" I should have just been able to param those keys.
Post a Comment