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
The current age of digital transformation means that IT organizations must adapt their toolset to cover all digital experiences, beyond just the end users’. Today’s businesses can no longer focus solely on the digital interactions they manage with employees or customers; they must now contend with non-traditional factors. Whether it's the power of brand to make or break a company, the need to monitor across all locations 24/7, or the ability to proactively resolve issues, companies must adapt to...
With major technology companies and startups seriously embracing Cloud strategies, now is the perfect time to attend 21st Cloud Expo October 31 - November 2, 2017, at the Santa Clara Convention Center, CA, and June 12-14, 2018, at the Javits Center in New York City, NY, and learn what is going on, contribute to the discussions, and ensure that your enterprise is on the right path to Digital Transformation.
Artificial intelligence, machine learning, neural networks. We’re in the midst of a wave of excitement around AI such as hasn’t been seen for a few decades. But those previous periods of inflated expectations led to troughs of disappointment. Will this time be different? Most likely. Applications of AI such as predictive analytics are already decreasing costs and improving reliability of industrial machinery. Furthermore, the funding and research going into AI now comes from a wide range of com...
"When we talk about cloud without compromise what we're talking about is that when people think about 'I need the flexibility of the cloud' - it's the ability to create applications and run them in a cloud environment that's far more flexible,” explained Matthew Finnie, CTO of Interoute, in this SYS-CON.tv interview at 20th Cloud Expo, held June 6-8, 2017, at the Javits Center in New York City, NY.
Internet of @ThingsExpo, taking place October 31 - November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA, is co-located with 21st Cloud Expo and will feature technical sessions from a rock star conference faculty and the leading industry players in the world. The Internet of Things (IoT) is the most profound change in personal and enterprise IT since the creation of the Worldwide Web more than 20 years ago. All major researchers estimate there will be tens of billions devic...
SYS-CON Events announced today that MobiDev, a client-oriented software development company, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. MobiDev is a software company that develops and delivers turn-key mobile apps, websites, web services, and complex software systems for startups and enterprises. Since 2009 it has grown from a small group of passionate engineers and business...
SYS-CON Events announced today that GrapeUp, the leading provider of rapid product development at the speed of business, will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Grape Up is a software company, specialized in cloud native application development and professional services related to Cloud Foundry PaaS. With five expert teams that operate in various sectors of the market acr...
SYS-CON Events announced today that Ayehu will exhibit at SYS-CON's 21st International Cloud Expo®, which will take place on October 31 - November 2, 2017 at the Santa Clara Convention Center in Santa Clara California. Ayehu provides IT Process Automation & Orchestration solutions for IT and Security professionals to identify and resolve critical incidents and enable rapid containment, eradication, and recovery from cyber security breaches. Ayehu provides customers greater control over IT infras...
In this presentation, Striim CTO and founder Steve Wilkes will discuss practical strategies for counteracting fraud and cyberattacks by leveraging real-time streaming analytics. In his session at @ThingsExpo, Steve Wilkes, Founder and Chief Technology Officer at Striim, will provide a detailed look into leveraging streaming data management to correlate events in real time, and identify potential breaches across IoT and non-IoT systems throughout the enterprise. Strategies for processing massive ...
SYS-CON Events announced today that Cloud Academy named "Bronze Sponsor" of 21st International Cloud Expo which will take place October 31 - November 2, 2017 at the Santa Clara Convention Center in Santa Clara, CA. Cloud Academy is the industry’s most innovative, vendor-neutral cloud technology training platform. Cloud Academy provides continuous learning solutions for individuals and enterprise teams for Amazon Web Services, Microsoft Azure, Google Cloud Platform, and the most popular cloud com...
In his session at Cloud Expo, Alan Winters, an entertainment executive/TV producer turned serial entrepreneur, presented a success story of an entrepreneur who has both suffered through and benefited from offshore development across multiple businesses: The smart choice, or how to select the right offshore development partner Warning signs, or how to minimize chances of making the wrong choice Collaboration, or how to establish the most effective work processes Budget control, or how to ma...
SYS-CON Events announced today that Enzu will exhibit at SYS-CON's 21st Int\ernational Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. Enzu’s mission is to be the leading provider of enterprise cloud solutions worldwide. Enzu enables online businesses to use its IT infrastructure to their competitive advantage. By offering a suite of proven hosting and management services, Enzu wants companies to focus on the core of their ...
SYS-CON Events announced today that IBM has been named “Diamond Sponsor” of SYS-CON's 21st Cloud Expo, which will take place on October 31 through November 2nd 2017 at the Santa Clara Convention Center in Santa Clara, California.
We build IoT infrastructure products - when you have to integrate different devices, different systems and cloud you have to build an application to do that but we eliminate the need to build an application. Our products can integrate any device, any system, any cloud regardless of protocol," explained Peter Jung, Chief Product Officer at Pulzze Systems, in this SYS-CON.tv interview at @ThingsExpo, held November 1-3, 2016, at the Santa Clara Convention Center in Santa Clara, CA
SYS-CON Events announced today that CA Technologies has been named "Platinum Sponsor" of SYS-CON's 21st International Cloud Expo®, which will take place October 31-November 2, 2017, at the Santa Clara Convention Center in Santa Clara, CA. CA Technologies helps customers succeed in a future where every business - from apparel to energy - is being rewritten by software. From planning to development to management to security, CA creates software that fuels transformation for companies in the applic...
Amazon started as an online bookseller 20 years ago. Since then, it has evolved into a technology juggernaut that has disrupted multiple markets and industries and touches many aspects of our lives. It is a relentless technology and business model innovator driving disruption throughout numerous ecosystems. Amazon’s AWS revenues alone are approaching $16B a year making it one of the largest IT companies in the world. With dominant offerings in Cloud, IoT, eCommerce, Big Data, AI, Digital Assista...
Multiple data types are pouring into IoT deployments. Data is coming in small packages as well as enormous files and data streams of many sizes. Widespread use of mobile devices adds to the total. In this power panel at @ThingsExpo, moderated by Conference Chair Roger Strukhoff, panelists looked at the tools and environments that are being put to use in IoT deployments, as well as the team skills a modern enterprise IT shop needs to keep things running, get a handle on all this data, and deliver...
In his session at @ThingsExpo, Eric Lachapelle, CEO of the Professional Evaluation and Certification Board (PECB), provided an overview of various initiatives to certify the security of connected devices and future trends in ensuring public trust of IoT. Eric Lachapelle is the Chief Executive Officer of the Professional Evaluation and Certification Board (PECB), an international certification body. His role is to help companies and individuals to achieve professional, accredited and worldwide re...
With the introduction of IoT and Smart Living in every aspect of our lives, one question has become relevant: What are the security implications? To answer this, first we have to look and explore the security models of the technologies that IoT is founded upon. In his session at @ThingsExpo, Nevi Kaja, a Research Engineer at Ford Motor Company, discussed some of the security challenges of the IoT infrastructure and related how these aspects impact Smart Living. The material was delivered interac...
IoT solutions exploit operational data generated by Internet-connected smart “things” for the purpose of gaining operational insight and producing “better outcomes” (for example, create new business models, eliminate unscheduled maintenance, etc.). The explosive proliferation of IoT solutions will result in an exponential growth in the volume of IoT data, precipitating significant Information Governance issues: who owns the IoT data, what are the rights/duties of IoT solutions adopters towards t...