-
<!---
-
Purpose: To provide different means of handling error in a generic way for CFMX 6.1
-
Attributes:
-
type="custom | database | any | application | lock | template | security | object | expression | normal | missinginclude" -default "normal"
-
sendEmail="yes | no" -default no
-
message="[some error message to be displayed]" -default "No error message specified." -notes Should only be specified when having a "normal" type error
-
additionalDetail="[some error detail to be displayed]" -default "No additionalDetail specified."
-
debug="yes|no" -default "no"
-
to="[email address to send email to]" -default "errors@my-site-here.com"
-
from="[from email address]" -default "#application.applicationname#.errors@my-site-here.com"
-
errorfile="#errorfile#" -defualt errorfile.cfm
-
Usage Notes:
-
if installed under custom tags directory:
-
<cf_errorHandler [type="custom|database|any|application|lock|template|security|object|expression|normal|missinginclude"] [sendEmail="yes|no"] [message="#somemessage#"] [details="#somedetails#"] [url="#url"] [debug="yes|no"]>
-
if installed in relative directory to your application:
-
<cfmodule template="#path#/errorHandler.cfm" [type="custom|database|any|application|lock|template|security|object|expression|normal|missinginclude"] [sendEmail="yes|no"] [message="#somemessage#"] [details="#somedetails#"] [url="#url"] [debug="yes|no"]>
-
if this custom tag has thesame name as another tag in custom tags directory:
-
<cfmodule name="#dir#.#dir2#.errorHandler"[type="custom|database|any|application|lock|template|security|object|expression|normal|missinginclude"] [sendEmail="yes|no"] [message="#somemessage#"] [details="#somedetails#"] [url="#url"][debug="yes|no"]>
-
--->
-
<!--- Set default values on attributes --->
-
<cfparam name="attributes.sendEmail" default="no">
-
<cfparam name="attributes.message" default="No error message specified.">
-
<cfparam name="attributes.additionalDetail" default="No additionalDetail specified.">
-
<cfparam name="attributes.type" default="normal">
-
<cfparam name="attributes.debug" default="no">
-
<cfparam name="attributes.errorfile" default="">
-
<cfparam name="attributes.sourcefile" default="unknown">
-
<cfparam name="attributes.to" default="errors@my-site-here.com">
-
<cfparam name="attributes.errorTemplate" default="No error template specified.">
-
<!--- offending app --->
-
<cftry>
-
<cfset appName = Application.ApplicationName>
-
<cfcatch>
-
<cfset appName = "">
-
</cfcatch>
-
</cftry>
-
<!--- create a unique id for each error; based on appName timestamp random num --->
-
<cfset errorID = appName & "_">
-
<cfset errorID = errorID & DateFormat(now(), "yyyy-mm-dd") & "_">
-
<cfset errorID = errorID & TimeFormat(Now(), "hh-mm-ss-l") & "_">
-
<cfset errorID = errorID & RandRange(1,9999)>
-
<!--- if it's a custom error type (like cfthrow), then create variables differently --->
-
<cfif attributes.type IS "custom">
-
<!--- get template and message from caller --->
-
<cfset errorTemplate = attributes.errorTemplate>
-
<cfset errorLine = "???">
-
<cfset errorMsg = attributes.message>
-
<cfelse>
-
<!--- get offending template and line --->
-
<cftry>
-
<!--- look at the rootcause level first --->
-
<cfset errorTemplate = Caller.CFCatch.rootcause.tagContext[1].template>
-
<cfset errorLine = Caller.CFCatch.rootcause.tagContext[1].line>
-
<cfcatch>
-
<cftry>
-
<!--- then check above that, for when the error type is "Template" --->
-
<cfset errorTemplate = Caller.CFCatch.tagContext[1].template>
-
<cfset errorLine = Caller.CFCatch.tagContext[1].line>
-
<cfcatch>
-
<cfset errorTemplate = "tagContext[1].template couldn't be captured">
-
<cfset errorLine = "tagContext[1].line couldn't be captured">
-
</cfcatch>
-
</cftry>
-
</cfcatch>
-
</cftry>
-
<!--- get error message --->
-
<cftry>
-
<!--- look at the rootcause level first --->
-
<cfset errorMsg = Caller.CFCatch.rootcause.message>
-
<cfcatch>
-
<cftry>
-
<!--- then check above that, for when the error type is "Template" --->
-
<cfset errorMsg = Caller.CFCatch.message>
-
<cfcatch>
-
<cfset errorMsg = "error message couldn't be captured">
-
</cfcatch>
-
</cftry>
-
</cfcatch>
-
</cftry>
-
<!--- /check for custom type --->
-
</cfif>
-
<!--- check if application name exist --->
-
<cfif Len(appName)>
-
<cfset tmpStr = "#appName#.">
-
<cfelse>
-
<cfset tmpStr = "">
-
</cfif>
-
<cfparam name="attributes.from" default="#tmpStr#errors@my-site-here.com">
-
<!--- needed to support fusebox --->
-
<cfif isDefined("CALLER.dsn")>
-
<cfset dsn = CALLER.dsn>
-
<cfelseif isDefined("ATTRIBUTES.dsn")>
-
<cfset dsn = ATTRIBUTES.dsn>
-
<cfelse>
-
<cfset dsn = "UNDEFINED!!">
-
</cfif>
-
<!--- Make sure no garbage was given as a value for the type attribute. --->
-
<cfswitch expression="#lcase(attributes.type)#">
-
<cfcase value="normal,any,application,database,expression,missinginclude,template,object,security,lock,custom" delimiters=",">
-
</cfcase>
-
<cfdefaultcase>
-
<cfset variables.subtype = attributes.type>
-
<cfset attributes.type = "unknown">
-
</cfdefaultcase>
-
</cfswitch>
-
<cfsavecontent variable="errorText">
-
<cfoutput>
-
<strong>Template:</strong><br>
-
#errorTemplate# (line: #errorLine#)<br>
-
<strong>Message:</strong><br>
-
#errorMsg#<br>
-
<strong>Additional Details:</strong><br>
-
#attributes.additionalDetail#<br>
-
<strong>Type:</strong><br>
-
#attributes.type#<br>
-
<strong>DSN:</strong><br>
-
#dsn#<br>
-
<strong>Date of error:</strong><br>
-
#DateFormat(now(), "mm/dd/yyyy")#<br>
-
<strong>Time of error:</strong><br>
-
#TimeFormat(now(), "hh:mm:ss")#<br>
-
<strong>errorID:</strong> #errorID#<br>
-
<br>
-
</cfoutput>
-
<!--- loop through the application structure (if it exits) and print out the variables --->
-
<u>Application variables:</u><br>
-
<cfif IsDefined("APPLICATION") AND IsStruct(APPLICATION) AND StructCount(APPLICATION)>
-
<cfloop collection="#application#" item="itm">
-
<cfif IsObject(application[itm]) OR IsStruct(application[itm])>
-
<!--- <cfdump var="#application[itm]#"> --->
-
<cfoutput>
-
<strong>#itm#</strong>: StructCount (#StructCount(application[itm])#)<br>
-
</cfoutput>
-
<cfelse>
-
<cfoutput>
-
<strong>#itm#</strong>: #application[itm]#<br>
-
</cfoutput>
-
</cfif>
-
</cfloop>
-
<cfelse>
-
None Defined
-
</cfif>
-
<!---
-
<cftry>
-
<cfdump var="#Exception#" label="Exception" expand="true">
-
<cfcatch>couldn't dump Exception<br></cfcatch>
-
</cftry><br>
-
<br> --->
-
<!--- only try this dump if Caller.CFCatch is available --->
-
<cfif IsDefined("Caller.CFCatch")>
-
<cftry>
-
<br>
-
<cfloop collection="#Caller.cfcatch#" item="i">
-
<cfset data = StructFind(Caller.cfcatch, i)>
-
<cfif IsSimpleValue(data) AND (Not i CONTAINS "stacktrace")>
-
<cfoutput><strong>#Ucase(i)#</strong> = #data#<br></cfoutput>
-
</cfif>
-
</cfloop>
-
<cfset tagContextInfo = "">
-
<!--- loop thru array of templates and stick it into a comma-delimited list --->
-
<cfloop index="i" from="1" to="#ArrayLen(Caller.CFCATCH.TAGCONTEXT)#">
-
<cfset stCurrent = Caller.CFCATCH.TAGCONTEXT[i]>
-
<cfset tagContextInfo = tagContextInfo & "ID: " & stCurrent["ID"]>
-
<cfset tagContextInfo = tagContextInfo & "<br> LINE: " & stCurrent["LINE"]>
-
<cfset tagContextInfo = tagContextInfo & "<br> TEMPLATE: " & stCurrent["TEMPLATE"] & "<br><br>">
-
</cfloop>
-
<cfoutput>
-
<br>
-
<strong><u>Tag Context:</u></strong><br>
-
#tagContextInfo#
-
</cfoutput>
-
<cfcatch>couldn't dump Caller.CFCatch</cfcatch>
-
</cftry><br>
-
<br>
-
<!--- TODO: implement this CF hot fix, so the code below can run:
-
http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=1a9c83c
-
<cftry>
-
<cfdump var="#Caller.CFCatch#" label="Caller.CFCatch" expand="true">
-
<cfcatch>couldn't dump Caller.CFCatch</cfcatch>
-
</cftry><br>
-
<br> --->
-
</cfif>
-
<cftry>
-
<cfdump var="#Client#" label="Client" expand="true">
-
<cfcatch>couldn't dump Client scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
<!--- since we use FB, and use the attributes scope liberally, dump it --->
-
<cftry>
-
<cfdump var="#Caller.attributes#" label="Caller.attributes" expand="true">
-
<cfcatch>couldn't dump Caller.attributes scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
<cftry>
-
<cfdump var="#Form#" label="Form" expand="true">
-
<cfcatch>couldn't dump Form scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
<cftry>
-
<cfdump var="#URL#" label="URL" expand="true">
-
<cfcatch>couldn't dump URL scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
<cftry>
-
<cfdump var="#CGI#" label="CGI" expand="true">
-
<cfcatch>couldn't dump CGI scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
<cftry>
-
<cfdump var="#Cookie#" label="Cookie" expand="true">
-
<cfcatch>couldn't dump Cookie scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
<cftry>
-
<cfdump var="#Session#" label="Session" expand="true">
-
<cfcatch>couldn't dump Session scope<br></cfcatch>
-
</cftry><br>
-
<br>
-
</cfsavecontent>
-
<!--- Sends the email with all of the approriate info to the administrator --->
-
<cfif Trim(attributes.sendEmail) is "yes">
-
<cfmail to="#attributes.to#"
-
from="#attributes.from#"
-
subject="An error has occurred; ID: #errorID#"
-
timeout="900"
-
type="HTML">
-
#errorText#
-
</cfmail>
-
</cfif>
-
<!---
-
if debug is set to yes just throw all pertinent info to the screen; otherwise forward to
-
customized error file
-
--->
-
<cfif attributes.debug eq "yes">
-
<cfoutput>#errorText#</cfoutput>
-
</body>
-
</html>
-
<cfelse>
-
<cfif attributes.errorfile NEQ "">
-
<cf_location url="#attributes.errorfile#" addtoken="false">
-
</cfif>
-
</cfif>