Welcome!

ColdFusion Authors: Greg Ness, Liz McMillan, Pat Romanski, Andreas Grabner, David Strom

Related Topics: ColdFusion

ColdFusion: Article

To Err Is Human, to Gracefully Handle Errors Is Divine

To Err Is Human, to Gracefully Handle Errors Is Divine

Have you ever seen a ColdFusion error page - the bordered box on a white background that basically says someone (or something) messed up? I'm sure you have, as I'm sure your users have too. Errors, and error messages, are an unfortunate fact of development life. But while you may have to live with occasional errors, you definitely do not (and should not) have to live with that too-oft-seen CF error screen.

Prettier Error Pages
The standard ColdFusion error screen is very informative and useful. So what's wrong with it? Actually, several things:

  • It's ugly, simple as that.
  • It won't match the look and feel of your site (I hope).
  • It's informative, but sometimes much too informative (you might not want end users knowing all the gory details of your filenames, paths, databases, queries, variables, or worse, your mistakes).
  • The sum of the prior bullets is that the standard error screens don't create a professional (and confidence-inspiring) impression.

    The simple solution is to use the <CFERROR> tag, which lets you replace the standard error screens with ones of your own. For example:

    <!--- Specify error page --->
    <CFERROR TYPE="request"
    TEMPLATE="/error/standard.cfm">
    Once this code is executed, the standard.cfm file (in the error directory) will be displayed instead of the default error screen. Within the file itself any and all client technologies may be used (HTML, JavaScript, DHTML, images, etc.).

    However, CFML may not be used within <CFERROR> files. After all, if an error condition has occurred, allowing the execution of CFML could in turn generate an additional error, causing the code to execute again, generating yet another error causing...you get the idea. So no CFML tags or functions. Instead, a special set of variables is made available to you within error pages, and you can place them in your code to refer to things like:

    • Date and time
    • Browser
    • Client IP address
    • Template name
    • Referring page
    Using <CFERROR> and these variables it's possible to create consistent and better-looking error screens, while also controlling (to some degree) the amount of information presented to users.

    <CFERROR> can also be used to define other error screens, for example, the screen displayed when form validation fails.

    Note: <CFERROR> needs to be executed on each request, so the ideal location for this tag is the Application.cfm page.

    Understanding Exception Handling
    <CFERROR> and error handling are very useful in presenting a better and more professional end-user experience, but <CFERROR> is not enough. After all, displaying a prettier error screen is wonderful but:

    • When an error occurs you still won't know about it.
    • If an error occurs, it will likely keep recurring; with <CFERROR> you can't fix or handle the situation.
    • When an error occurs, processing stops; you can't gracefully handle the error and keep going.
    In other words, <CFERROR> lets you replace the error page, but that's it. It doesn't let you handle errors - processing them or taking actions when they occur.

    That's where exception handling comes into play, with an emphasis on handling. Exception handling is a mechanism by which errors (or other conditions) may be trapped and then responded to. Using exception-handling error conditions doesn't halt processing, instead processing is diverted to special blocks of code that you can write - code that can do just about anything you need.

    Try and Catch
    Exception handling in ColdFusion is implemented using a try/catch interface, implemented (as you'd expect) using tags named <CFTRY> and <CFCATCH>. The basic flow is like this:

    start code block
    CFML code goes here
    error handling block
    error handling code goes here
    end error handling block
    end code block
    Any code in which exception handling is to be used must be flagged - the start and end so noted. Exception-handling code is then placed at the end of the code block. Then, if an exception occurs within your code, processing is stopped and control is transferred to the error-handling code.

    The CFML code looks like this:

    <CFTRY>
    ... CFML code ...
    <CFCATCH>
    ... CFML code ...
    </CFCATCH>
    </CFTRY>
    <CFTRY> and </CFTRY> delimit the code in which exceptions are to be trapped, and ColdFusion tries (and thus <CFTRY>) to execute it. If an exception occurs (this is actually referred to as an error being thrown), it's caught by the exception-handling code (and thus <CFCATCH>).

    For example, if you want to send an e-mail to an administrator when an exception is thrown, you could do something like this:

    <CFTRY>
    ... CFML code ...
    <CFCATCH>
    <CFMAIL TO="admin@domain.com"
    FROM=" admin@domain.com"
    SUBJECT="Error on #GetCurrentTemplatePath()#">
    TYPE:
    #CFCATCH.type#

    MESSAGE:
    #CFCATCH.message#
    </CFMAIL>
    </CFCATCH>
    </CFTRY>
    The <CFCATCH> block here contains a <CFMAIL> tag, so when an exception is thrown, an e-mail message is sent to the specified address and processing continues (to whatever code comes next).

    Handling Specific Exceptions
    As you can see, trapping and handling exceptions is not complicated at all. But what if you want to handle different types of exceptions in different ways? That's doable too - all you need is multiple <CFCATCH> blocks, one for each type of exception.

    Look at the following code snippet:

    <CFTRY>
    ...
    <CFCATCH TYPE="missinginclude">
    ...
    </CFCATCH>
    <CFCATCH TYPE="database">
    ...
    </CFCATCH>
    <CFCATCH TYPE="lock">
    ...
    </CFCATCH>
    <CFCATCH TYPE="any">
    ...
    </CFCATCH>
    </CFTRY>
    Here four catch blocks are used. The first catches failed <CFINCLUDE> tags, the second catches database problems (including ODBC and SQL errors), the third catches <CFLOCK> errors (including timeouts and missing locks), and the fourth catches all other errors. It's a good idea to always have one <CFCATCH> with TYPE="any" to catch any exceptions not specifically caught, and to specify it last (otherwise it'll catch exceptions that you might not want it to).

    Other exception types are supported, including over 50 advanced types (used to catch very specific exceptions, like <CFPOP> authentication failures) and custom types used to define exception types of your own.

    Using Exception Handling
    We've only just scratched the surface here; there's lots more to exception handling and what you can do using this functionality. Here are some things to consider:

  • The earlier examples used exception handling purely for notification purposes, but as you can execute any CFML code within <CFCATCH> blocks, you can do just about anything (including executing <CFQUERY> tags, writing log files, setting APPLICATION variables to point to other servers, and more).
  • Exception handling can be nested. This allows you to provide high-level handling for complete pages, and more granular handling for specific operations. For example, placing a <CFQUERY> tag within its own <CFTRY> block would enable you to retry timed-out queries, or resubmit them to a backup database.
  • When nesting exception handling, exceptions can be passed to outer <CFTRY> blocks by re-throwing them using the <CFRETHROW> tag.
  • Developers can throw (generate) their own exceptions using the <CFTHROW> tag. For example, an exception could be thrown if required parameters are not passed, so as to centralize processing and the displaying of error messages.
  • The code in custom tags should have its own internal exception handling; mechanisms exist for passing exceptions to calling pages if needed.

    And that's just the start of it.

    Summary
    At a minimum, every developer should be using <CFERROR> to override the default error screens with ones that better match the look and feel of the application. However, <CFERROR> is just the beginning. Exception handling is not difficult to implement and should be used to create better applications - better for you and better for your users.

    Neo, which I'll be covering extensively starting next month, extends ColdFusion's try/catch handling even further. If you have yet to play with these tags, there couldn't be a better time to start.

  • More Stories By Ben Forta

    Ben Forta is Adobe's Senior Technical Evangelist. In that capacity he spends a considerable amount of time talking and writing about Adobe products (with an emphasis on ColdFusion and Flex), and providing feedback to help shape the future direction of the products. By the way, if you are not yet a ColdFusion user, you should be. It is an incredible product, and is truly deserving of all the praise it has been receiving. In a prior life he was a ColdFusion customer (he wrote one of the first large high visibility web sites using the product) and was so impressed he ended up working for the company that created it (Allaire). Ben is also the author of books on ColdFusion, SQL, Windows 2000, JSP, WAP, Regular Expressions, and more. Before joining Adobe (well, Allaire actually, and then Macromedia and Allaire merged, and then Adobe bought Macromedia) he helped found a company called Car.com which provides automotive services (buy a car, sell a car, etc) over the Web. Car.com (including Stoneage) is one of the largest automotive web sites out there, was written entirely in ColdFusion, and is now owned by Auto-By-Tel.

    Comments (1) View Comments

    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.


    Most Recent Comments
    xavi 05/20/03 08:53:00 AM EDT