|
ColdFusion 9.0 Resources |
Example: using nested tags, cfthrow, and cfrethrowThe following example shows many of the discussed techniques including nested cftry blocks and the cfthrow and cfrethrow tags. The example includes a simple calling page and a custom tag page:
The calling pageThe calling page represents a section from a larger application page. To keep things simple, the example hard-codes the name to be looked up. <cftry>
<cf_getEmps EmpName="Jones">
<cfcatch type="myApp.getUser.noEmpName">
<h2>Oops</h2>
<cfoutput>#cfcatch.Message#</cfoutput><br>
</cfcatch>
</cftry>
<cfif isdefined("getEmpsResult")>
<cfdump var="#getEmpsResult#">
</cfif>
Reviewing the codeThe following table describes the code:
The custom tag pageThe custom tag page searches for the name in the database and returns any matching records in a getEmpsResult variable in the calling page. It includes several nested cftry blocks to handle error conditions. For a full description, see Reviewing the code section, following the example: Save the following code as getEmps.cfm in the same directory as the calling page. <!--- If the tag didn't pass an attribute, throw an error to be handled by
the calling page --->
<cfif NOT IsDefined("attributes.EmpName")>
<cfthrow Type="myApp.getUser.noEmpName"
message = "Last Name was not supplied to the cf_getEmps tag.">
<cfexit method = "exittag">
<!--- Have a name to look up --->
<cfelse>
<!--- Outermost Try Block --->
<cftry>
<!--- Inner Try Block --->
<cftry>
<!--- Try to query the main database and set a caller variable to the result --->
<cfquery Name = "getUser" DataSource="cfdocexamples">
SELECT *
FROM Employee
WHERE LastName = '#attributes.EmpName#'
</cfquery>
<cfset caller.getEmpsResult = getuser>
<!--- If the query failed with a database error, check the error type
to see if the database was found --->
<cfcatch type= "Database">
<cfif (cfcatch.SQLState IS "S100") OR (cfcatch.SQLState IS
"IM002")>
<!--- If the database wasn't found, try the backup database --->
<!--- Use a third-level Try block --->
<cftry>
<cfquery Name = "getUser" DataSource="cfdocexamplesBackup">
SELECT *
FROM Employee
WHERE LastName = '#attributes.EmpName#'
</cfquery>
<cfset caller.getEmpsResult = getuser>
<!--- If still get a database error, just return to the calling page
without setting the caller variable. There is no cfcatch body.
This might not be appropriate in some cases.
The Calling page ends up handling this case as if a match was not
found --->
<cfcatch type = "Database" />
<!--- Still in innermost try block. Rethrow any other errors to the next
try block level --->
<cfcatch type = "Any">
<cfrethrow>
</cfcatch>
</cftry>
<!--- Now in second level try block.
Throw all other types of Database exceptions to the next try
block level --->
<cfelse>
<cfrethrow>
</cfif>
</cfcatch>
<!--- Throw all other exceptions to the next try block level --->
<cfcatch type = "Any">
<cfrethrow>
</cfcatch>
</cftry>
<!--- Now in Outermost try block.
Handle all unhandled exceptions, including rethrown exceptions, by
displaying a message and exiting to the calling page.--->
<cfcatch Type = "Any">
<h2>Sorry</h2>
<p>An unexpected error happened in processing your user inquiry.
Please report the following to technical support:</p>
<cfoutput>
Type: #cfcatch.Type#
Message: #cfcatch.Message#
</cfoutput>
<cfexit method = "exittag">
</cfcatch>
</cftry>
</cfif>
Reviewing the codeThe following table describes the code:
Testing the codeTo test the various ways errors can occur and be handled in this example, try the following:
|