Welcome!

You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Toward Better Error Handling - Part 4

Toward Better Error Handling - Part 4

If you've programmed in a modern programming language (Java, C, JavaScript, or even stored procedure languages), you've probably heard of exception handling via try/catch statements. ColdFusion supports the same capability.

If you're new to using them, I'll explain how they're used, and even experienced programmers may learn a thing or two about CF's particular use of try/catch exception handling.

This is the fourth in a series on error handling (see CFDJ, Vol. 2, issues 10 and 12, and Vol. 3, issue 2). In the three previous installments, we've focused on handling errors at the page level. Something goes wrong, and you want to do something other than have the user see the typical CF error message. That rather cryptic, black-on-white message is great for developers but it's not useful to end users, and we discussed several ways to improve on that.

In this article, we'll move a level further down the "error-handling hierarchy" introduced in Part 2 (see Figure 1). With try/catch handling, or specifically the CFTRY/CFCATCH tags, we're generally designing a way to detect and handle an error that we suspect may happen at runtime, but that we can't know will always happen.

Why a CFTRY?
On a simple level, CFTRY and CFCATCH are used to handle a possible error that might arise in some code. Maybe the code is doing a database interaction that could fail due to integrity errors, or the database is unavailable. Perhaps you're attempting a CFHTTP and the connection to the remote site may fail. Or you're calling a COM or Java object and the object is unavailable.

In these or any circumstance like them, if you know an error may happen, you can anticipate and handle it. Of course, if you've implemented a CFERROR tag for your application (as discussed in the last issue), then it could handle the error, but that will be on a more global scale for the entire page or, indeed, application.

But if some particular tag (or function) or set of them may cause a problem that you can at least contemplate, then the CFTRY/CFCATCH pair will give you much finer control in handling the error. Indeed, handling the error may mean simply ignoring it, as we'll see later.

A Simple Example
CFTRY and CFCATCH work in tandem to:

  1. Identify the code to be monitored
  2. Describe how to handle any error that arises
The tags are always used together, and neither can be used without the other. The simplest form of using them is:
<CFTRY>
<!--- some code you want to monitor--->
<CFCATCH>
<!--- code to handle an error that arises --->
</CFCATCH>
</CFTRY>
A specific example might be:
<CFTRY>
<CFQUERY DATASOURCE="#request.dsn#"NAME="test">
SELECT * FROM MyTable
</CFQUERY>
<CFCATCH>

An Error has occurred while selecting records from MyTable.<p>
The details of the error are:<br>
<CFOUTPUT>#CFCATCH.MESSAGE# <p>#CFCATCH.DETAIL#
<CFABORT>
</CFCATCH>
</CFTRY>

There are a few very important things to note about what goes on within this process.

What Goes on Within the CFTRY/CFCATCH Process
If you're new to TRY/CATCH processing, you should be aware of the following when starting to use this processing. The processing differs depending on whether or not an error occurs in the code being "tried."

If No Error Occurs
If no error occurs while processing the code within the CFTRY block (the CFQUERY, in our example), then:

  1. None of the code in the CFCATCH would be executed
  2. Processing would continue with the next statement after the /CFTRY
In that sense, it's like a CFIF that tests for an error code from the code being tried and only does something if there's an error.

That's the really cool thing about TRY/CATCH processing: it's as if we now have return codes to test for CF tags. Of course, some processes (like CFQUERY) do in fact return a code (a database error code, that is), but we've never had a way to trap that error before Release 4. More on that in a moment. But just keep in mind that if an error does not occur, then processing simply skips the CFCATCH and continues after the /CFTRY.

If An Error Occurs
The more important processing is what takes place if there is an error within the code being tried. In that case:

  1. The statements within the CFCATCH (in our simple example) would be executed.
  2. The normal CF error message would not be displayed to the end user. You would be responsible for determining what message (if any) to show the user.
  3. No error message would be written to the CF error logs.
  4. After processing the error handling code within the CFCATCH (when an error has been trapped this way), execution will continue with the next statement following the /CFTRY, which may not always be what you intend. Note that we've used a CFABORT tag in the example above to stop execution.
Also note that within the CFCATCH sample code, we're able to perform any CF tag. We're using a CFOUTPUT to display some information to the user. We could also use a CFMAIL to send ourselves (as developers) some information on the error. We might create a log entry in a database, but be careful not to cause yet another error and, yes, you can nest another try/catch block within a catch. (One of the new features in Release 5, CFLOG, will allow us to programmatically write an entry in the CF application log file.)

CFCATCH Error Variables
Note also that the example shows us referring to some special variables within the CFCATCH, such as CFCATCH.MESSAGE and CFCATCH.DETAIL. In the previous articles, we discussed the ERROR.DIAGNOSTICS variable as well as ERROR.BROWSER, and more. While the "ERROR." variables are not available, there are several specific new CFCATCH variables. They always include at least those shown in Table 1.

There are a few other variables available when specific kinds of errors are being handled, including ErrNumber, LockName, LockOperation, MissingFileName, Native-ErrorCode, SQLState, ErrorCode, and ExtendedInfo. The CF documentation (the CFML Language Reference) contains more detail on each of these.

Keep in mind, too, that you have full access to all the other CF variables including CGI.HTTP_ USER_AGENT (in place of ERROR.BROWSER), so the loss of the "ERROR." variables is easily supplemented by the full range of CF variables providing the same information (indeed, the only reason the "ERROR." variables were created was because the original CFERROR handler couldn't process CF tags or variables, as was discussed in the last two articles).

Before leaving the subject of CFCATCH variables, note something about how CF will catch an exception thrown by a Java object (called via CFOBJECT). From the 4.5 New Features document: "ColdFusion checks if the exception thrown is the method exception and stores the classname of the exception in the CFCATCH.MESSAGE variable."

Anticipating Multiple Exceptions
Our simple example presumes that the error-handling routine in the CFCATCH is the only one necessary for the process being "tried." But it's certainly possible that the code may be doing several things, or that the error can have one of a number of causes. There are two ramifications of this:

  1. You may have multiple CFCATCH blocks within a single CFTRY.
  2. You may distinguish one CFCATCH from another, in that case, using an exception TYPE.
In fact, the Allaire documentation shows a TYPE being provided as if it's required. It's not. There is a default type (called any) which if it's not specified, is presumed. But you may trap for any number of error types in a manner such as:
<CFCATCH TYPE="Database">
or
<CFCATCH TYPE="Lock">
More types are provided in Table 2.

The last item - "custom_type" - literally means any phrase at all. As we'll learn later, your code can "throw" an exception within a CFTRY to be caught by CFCATCH. In such a case, you can choose to create your own "type" for the error-handling mechanism to look for.

Finally, be aware that there's also a possible type of "unknown" for certain exceptions caught by TYPE="ANY". And there are a whole host of types whose names start with "COM.Allaire.ColdFusion" that may be returned under certain conditions.

Again, you don't need to worry about catching a specific type if you're simply trying to catch any error that occurs. Leave the type off. Remember, you can view the type in the available CFCATCH.TYPE variable.

A Change in Processing Multiple CFCATCHes in 4.51
Before leaving the subject of multiple CFCATCHes, you should note that there was a change in behavior as of Release 4.51. The change can be set back to the former behavior via a new CFSETTING parameter. Following is a quote from the Release 4.51 notes:

CFCATCH selection logic in ColdFusion 4.5.1 differs slightly from ColdFusion 4.0.x. In Cold-Fusion 4.0.x, the first matching CFCATCH block encountered would be selected to handle an exception. ColdFusion 4.5 scans a CFTRY tag's entire list of CFCATCH blocks to find the closest match. For example, if a CFTRY tag has a CFCATCH TYPE= TEMPLATE block, followed by a CFCATCH TYPE=MISSINGINCLUDE block, ColdFusion 4.0.x will select the TEMPLATE block to handle a MISSINGINCLUDE exception, while ColdFusion 4.5.1 will select the MISSINGINCLUDE block. ColdFusion 4.5.1 can be reset to handle a template using ColdFusion 4.0.x rules by setting the compatibility setting, <cfsetting catchexceptionsbypattern=no>.

What You Can and Can't Catch
With all this talk about catching errors, it may help to take a moment to clarify what kind of things you can and cannot catch with CFTRY/CFCATCH.

Don't Wrap Entire Program in a Try!
Frequently, folks getting started with this tool presume that they can surround their entire program with a CFTRY to catch any error (or indeed they try to place an opening CFTRY in application.cfm and a closing one in onrequestend.cfm). It won't work, and in fact it's not necessary since that's basically what the new CFERROR TYPE="Exception" (discussed in the last article) does for you. It can catch any exception that occurs in your program that's not otherwise being handled by a CFTRY/CATCH.

Preventing Syntax Errors
You may lament that you can't be warned by an error handler when you've made a syntax mistake. We all make mistakes, right ? And who has time to thoroughly test every template, especially when it may be part of a long, multi-page process that can't easily be tested? But take heed: you can (and should) at least confirm that the code will complile, and you don't actually have to run it to find out. CF comes with a syntax checker. It's executed via a page in the CFDOCS directory on the Web server where CF is installed, at http://yourdomain/CFDOCS/cfmlsyntaxcheck/cfmlsyntaxcheck.cfm. Its also reached from the Welcome Page at http://yourdomain/CFDOCS/index.htm

Can't Catch Syntax Errors
Note, though, that I said catch any exception. I didn't say it can catch any error. CFTRY can't be used to catch a syntax error. If you think about it, it makes sense. If a syntax error is encountered, the interpreter stops processing right away. It doesn't matter if there's a CFTRY surrounding the code having the error. The interpreter will never begin executing the code.

That stresses the point that CFTRY is for catching "runtime" or execution errors. It can't catch compilation or syntax errors. (Again, CFERROR can help us here, but see the end of the article for more on when it may or may not catch syntax errors.)

Use It to Ignore Array Existence Errors
In a previous CFDJ article, "Testing Existence in Arrays," (Vol. 3, issue 4), I showed how attempting to refer to an array element that doesn't exist will generate a runtime exception. Unfortunately, there's simply no function to test for such existence (see the article for more on why IsDefined and others simply don't work in this circumstance). As the article demonstrated, you could wrap such array element references in a CFTRY and use CFCATCH to simply ignore the error (code no error message and use no CFABORT, so processing simply proceeds following the /CFTRY).

Use It to Catch Unavoidable Database Errors
I had mentioned previously that one of the neat things you can now do with a CFTRY is determine if a database error has occurred. Say "so long" to users confused about ODBC errors caused by bad SQL being created, databases being locked, or servers being down; now you can catch such an error and give the user a friendlier message.

Be Careful Using It to Catch Avoidable Database Errors
Be careful about this power for trapping database errors. Some have gone a bit too far and have used the capability in a way that wasn't intended and which may be more harmful than useful. For instance, if you're facing a decision in your code about whether to do an insert or an update, don't try an insert and then if it fails, do an update instead.

It may seem that it's saving you from having to do a test to see if the record already exists (in which case an update is the action to perform), but consider that the error causes the database connection to be lost. The time involved to re-create that connection may outweigh the performance gain from avoiding the quick check for the existence of a given primary key value. Just do a "Select keyname from tablename where keyname=value" (as opposed to a more wasteful "select *"), which should execute very quickly. (Often you can program your interface so that your insert/update page is passed information that indicates whether the process is to be an insert or update, with an update being indicated if the primary key is passed from a hidden form field.)

The same consideration about not overusing CFTRY for avoidable database errors applies when doing an insert or update to a record having a column with a uniqueness constraint. Consider a userID column. There should be only one. Whether it's the primary key or has a "unique index" on the column, there can never be more than one record with a given userID. So what can you do as you contemplate inserting or updating that column with a given value, since you don't want to proceed if there's already a record with that value?

The simple solution is to just do a select on that value to see if it already exists and report an error if it does. Some clever programmers wrap the insert or update in a try, and catch and report the uniqueness constraint error if the value already exists (which would violate the uniqueness constraint and cause the insert/update to fail). Their thinking is that database will do the same check for whether the value already exists on the insert/update, so why bother suffering the redundancy of doing it first themselves?

But the cost in the lost DB connection likely outweighs the savings of just checking if the value already exists. Your mileage may vary, but consider that uniqueness is enforced via an index, so the check you do first will be very fast. Plus, while the insert or update will proceed to do another check for that value's existence, consider that the check you've done first will have caused that result to be cached in the database engine by the time the second check is done, making the "redundancy" even less painful. (Thanks to Daryl Banttari, senior consultant for Macromedia Consulting, for offering that insight.)

Some Quirks in Studio
Before concluding, you should take note of some quirks in Studio that may make working with CFTRY and CFCATCH just a little more challenging than it should be. First, Studio doesn't create a closing tag for CFTRY or CFCATCH when you type the opening tag, as it does on all others (assuming you have tag completion enabled). You can add it to the autocompletion list in Studio using Options>Settings> Editor>Tag Completion, adding a new entry for both CFTRY and CFCATCH.

You may also notice that if you look for CFCATCH in the CFML Language Reference's alphabetical listing of tags, you won't find it. It's listed as CFTRY CFCATCH. That may make sense since it's really a subtag to CFTRY, but it's confusing at first. Worse still, pressing F1 on CFCATCH won't produce the expected help for the same reason.

More to Come
I've said in previous articles that this would be the last of four parts, but as I continue the series, I find there's lots more to cover. We still have the interesting CFERROR TYPE="monitor" to discuss. There's also more to talk about regarding intentionally "raising" an error (using CFTHROW), as well as how to provide substantial improvements in error handling when using modular programming (custom tags) with CFRETHROW.

And then there are quirks in the way a sitewide error handler will override a CFERROR TYPE="Request", as well as how a sitewide missing template handler won't catch a missing file in a CFINCLUDE or CFMODULE (you have to code your own CFERROR TYPE="EXCEPTION"EXCEPTION="MISSINGINCLUDE"). There are also quirks when a CFERROR TYPE="Exception" will catch a syntax error.

Still another quirk exists in the aforementioned "CATCHEXCEPTIONSBYPATTERN" process, which doesn't quite work as expected in some situations. When throwing a type of "x.foo", the docs say we should be able to catch it with type x, but it doesn't work. We'll get to all that eventually. As always, forewarned is forearmed.

We'll also eventually talk about how to get errors logged to the logs even when being handled by CFERROR or CFTRY (which will be even easier with the new CFLOG tag in CF 5), as well as how to detect and handle a long-running request (perhaps in a different way than other errors), and generally how you might detect and handle different "types" of errors in the CFERROR handlers, now that you know about the differences among such types.

I know some have wondered how I even got four articles out of the subject of error handling. From feedback so far, you agree that there is indeed more to it than many had imagined.

More Stories By Charlie Arehart

A veteran ColdFusion developer since 1997, Charlie Arehart is a long-time contributor to the community and a recognized Adobe Community Expert. He's a certified Advanced CF Developer and Instructor for CF 4/5/6/7 and served as tech editor of CFDJ until 2003. Now an independent contractor (carehart.org) living in Alpharetta, GA, Charlie provides high-level troubleshooting/tuning assistance and training/mentoring for CF teams. He helps run the Online ColdFusion Meetup (coldfusionmeetup.com, an online CF user group), is a contributor to the CF8 WACK books by Ben Forta, and is frequently invited to speak at developer conferences and user groups worldwide.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


@ThingsExpo Stories
From 2013, NTT Communications has been providing cPaaS service, SkyWay. Its customer’s expectations for leveraging WebRTC technology are not only typical real-time communication use cases such as Web conference, remote education, but also IoT use cases such as remote camera monitoring, smart-glass, and robotic. Because of this, NTT Communications has numerous IoT business use-cases that its customers are developing on top of PaaS. WebRTC will lead IoT businesses to be more innovative and address...
In his opening keynote at 20th Cloud Expo, Michael Maximilien, Research Scientist, Architect, and Engineer at IBM, discussed the full potential of the cloud and social data requires artificial intelligence. By mixing Cloud Foundry and the rich set of Watson services, IBM's Bluemix is the best cloud operating system for enterprises today, providing rapid development and deployment of applications that can take advantage of the rich catalog of Watson services to help drive insights from the vast t...
SYS-CON Events announced today that Elastifile will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 - Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Elastifile Cloud File System (ECFS) is software-defined data infrastructure designed for seamless and efficient management of dynamic workloads across heterogeneous environments. Elastifile provides the architecture needed to optimize your hybrid cloud environment, by facilitating efficient...
Recently, IoT seems emerging as a solution vehicle for data analytics on real-world scenarios from setting a room temperature setting to predicting a component failure of an aircraft. Compared with developing an application or deploying a cloud service, is an IoT solution unique? If so, how? How does a typical IoT solution architecture consist? And what are the essential components and how are they relevant to each other? How does the security play out? What are the best practices in formulating...
In his session at @ThingsExpo, Arvind Radhakrishnen discussed how IoT offers new business models in banking and financial services organizations with the capability to revolutionize products, payments, channels, business processes and asset management built on strong architectural foundation. The following topics were covered: How IoT stands to impact various business parameters including customer experience, cost and risk management within BFS organizations.
SYS-CON Events announced today that Golden Gate University will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Since 1901, non-profit Golden Gate University (GGU) has been helping adults achieve their professional goals by providing high quality, practice-based undergraduate and graduate educational programs in law, taxation, business and related professions. Many of its courses are taug...
WebRTC is great technology to build your own communication tools. It will be even more exciting experience it with advanced devices, such as a 360 Camera, 360 microphone, and a depth sensor camera. In his session at @ThingsExpo, Masashi Ganeko, a manager at INFOCOM Corporation, will introduce two experimental projects from his team and what they learned from them. "Shotoku Tamago" uses the robot audition software HARK to track speakers in 360 video of a remote party. "Virtual Teleport" uses a...
When shopping for a new data processing platform for IoT solutions, many development teams want to be able to test-drive options before making a choice. Yet when evaluating an IoT solution, it’s simply not feasible to do so at scale with physical devices. Building a sensor simulator is the next best choice; however, generating a realistic simulation at very high TPS with ease of configurability is a formidable challenge. When dealing with multiple application or transport protocols, you would be...
SYS-CON Events announced today that DXWorldExpo has been named “Global Sponsor” of SYS-CON's 21st International Cloud Expo, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Digital Transformation is the key issue driving the global enterprise IT business. Digital Transformation is most prominent among Global 2000 enterprises and government institutions.
21st International Cloud Expo, taking place October 31 - November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA, will feature technical sessions from a rock star conference faculty and the leading industry players in the world. Cloud computing is now being embraced by a majority of enterprises of all sizes. Yesterday's debate about public vs. private has transformed into the reality of hybrid cloud: a recent survey shows that 74% of enterprises have a hybrid cloud strategy. Me...
SYS-CON Events announced today that Secure Channels, a cybersecurity firm, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Secure Channels, Inc. offers several products and solutions to its many clients, helping them protect critical data from being compromised and access to computer networks from the unauthorized. The company develops comprehensive data encryption security strategie...
In his session at @ThingsExpo, Sudarshan Krishnamurthi, a Senior Manager, Business Strategy, at Cisco Systems, discussed how IT and operational technology (OT) work together, as opposed to being in separate siloes as once was traditional. Attendees learned how to fully leverage the power of IoT in their organization by bringing the two sides together and bridging the communication gap. He also looked at what good leadership must entail in order to accomplish this, and how IT managers can be the ...
Recently, WebRTC has a lot of eyes from market. The use cases of WebRTC are expanding - video chat, online education, online health care etc. Not only for human-to-human communication, but also IoT use cases such as machine to human use cases can be seen recently. One of the typical use-case is remote camera monitoring. With WebRTC, people can have interoperability and flexibility for deploying monitoring service. However, the benefit of WebRTC for IoT is not only its convenience and interopera...
There is only one world-class Cloud event on earth, and that is Cloud Expo – which returns to Silicon Valley for the 21st Cloud Expo at the Santa Clara Convention Center, October 31 - November 2, 2017. Every Global 2000 enterprise in the world is now integrating cloud computing in some form into its IT development and operations. Midsize and small businesses are also migrating to the cloud in increasing numbers. Companies are each developing their unique mix of cloud technologies and service...
When shopping for a new data processing platform for IoT solutions, many development teams want to be able to test-drive options before making a choice. Yet when evaluating an IoT solution, it’s simply not feasible to do so at scale with physical devices. Building a sensor simulator is the next best choice; however, generating a realistic simulation at very high TPS with ease of configurability is a formidable challenge. When dealing with multiple application or transport protocols, you would be...
SYS-CON Events announced today that App2Cloud will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on Oct. 31 – Nov 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. App2Cloud is an online Platform, specializing in migrating legacy applications to any Cloud Providers (AWS, Azure, Google Cloud).
IoT is at the core or many Digital Transformation initiatives with the goal of re-inventing a company's business model. We all agree that collecting relevant IoT data will result in massive amounts of data needing to be stored. However, with the rapid development of IoT devices and ongoing business model transformation, we are not able to predict the volume and growth of IoT data. And with the lack of IoT history, traditional methods of IT and infrastructure planning based on the past do not app...
To get the most out of their data, successful companies are not focusing on queries and data lakes, they are actively integrating analytics into their operations with a data-first application development approach. Real-time adjustments to improve revenues, reduce costs, or mitigate risk rely on applications that minimize latency on a variety of data sources. Jack Norris reviews best practices to show how companies develop, deploy, and dynamically update these applications and how this data-first...
Intelligent Automation is now one of the key business imperatives for CIOs and CISOs impacting all areas of business today. In his session at 21st Cloud Expo, Brian Boeggeman, VP Alliances & Partnerships at Ayehu, will talk about how business value is created and delivered through intelligent automation to today’s enterprises. The open ecosystem platform approach toward Intelligent Automation that Ayehu delivers to the market is core to enabling the creation of the self-driving enterprise.
Internet-of-Things discussions can end up either going down the consumer gadget rabbit hole or focused on the sort of data logging that industrial manufacturers have been doing forever. However, in fact, companies today are already using IoT data both to optimize their operational technology and to improve the experience of customer interactions in novel ways. In his session at @ThingsExpo, Gordon Haff, Red Hat Technology Evangelist, shared examples from a wide range of industries – including en...