Glossary

What Is CFTRY and CFCATCH?

Definition

CFTRY and CFCATCH are ColdFusion Markup Language (CFML) tags used for exception handling. They work together to safely run code that might fail and to respond gracefully if an error occurs. Think of as the “attempt” section and as the “what to do when it goes wrong” section. Typically, they are paired with CFFINALLY to run cleanup code no matter what happens.

In practical terms, and help you protect your application from unexpected issues—such as database errors, file access problems, or API timeouts—by allowing you to log the error, show user-friendly messages, and keep the system stable.


How It Works

Core Concept

  • Put risky operations inside .
  • Handle specific errors inside one or more blocks (by type).
  • Optionally add to run code that should always execute (e.g., closing files, releasing locks).

Control flow (Step-by-Step)

  1. ColdFusion executes code inside .
  2. If no exception occurs, ColdFusion skips all blocks and moves to (if present), then continues.
  3. If an exception occurs, ColdFusion checks each in order to find a match by type.
  4. The first matching runs. If none match, a more general catch like type=”any” (or no match) will handle or bubble the error.
  5. After , executes if present.
See also  What Is CFTHREAD in ColdFusion?

Syntax Overview

Basic structure:













Common Types

Use specific types first to avoid masking critical problems:

  • application: For application-level exceptions
  • database: SQL errors (query, stored procedures, timeouts)
  • Security: Permission and authorization issues
  • template: Template parsing or compilation errors
  • expression: Expression evaluation failures (division by zero, etc.)
  • missinginclude: Missing included templates
  • object: CFC instantiation and method-calling errors
  • type: Type coercion or parameter type mismatches
  • lock: Locking timeouts
  • any: Catch-all for exceptions not matched by earlier types

Tip: In Adobe ColdFusion and Lucee, the exact set of types and their behavior may vary slightly. Always consult your engine’s documentation.


Practical Syntax Examples

Example 1: Handling Database Exceptions



SELECT * FROM Users WHERE UserID =












Example 2: Always Clean Up With











Real-World Use Case: Upload, Validate, Save, and Roll Back Safely

Imagine a feature where a user uploads a product image and details, which you then save to disk and insert into a database. A failure in any step should not leave partial data behind.





    <!--- 2) Validate metadata --->
    <cfif len(trim(form.productName)) EQ 0>
        <cfthrow type="validation" message="Product name is required.">
    </cfif>

    <!--- 3) Save to DB --->
    <cfquery name="qInsert" datasource="MyDSN">
        INSERT INTO Products (Name, ImagePath, Price)
        VALUES (
            <cfqueryparam value="#form.productName#" cfsqltype="cf_sql_varchar">,
            <cfqueryparam value="#uploadedPath#" cfsqltype="cf_sql_varchar">,
            <cfqueryparam value="#form.price#" cfsqltype="cf_sql_decimal">
        )
    </cfquery>

    <cftransaction action="commit">
</cftransaction>

<cfcatch type="validation">
    <cftransaction action="rollback">
    <!--- Remove uploaded file since DB insert failed --->
    <cfif fileExists(expandPath('/uploads/' & uploadedPath))>
        <cffile action="delete" file="#expandPath('/uploads/' & uploadedPath)#">
    </cfif>
    <cfset request.userMessage = "Please fix: #cfcatch.message#">
</cfcatch>

<cfcatch type="database">
    <cftransaction action="rollback">
    <cflog file="app" text="DB error inserting product: #cfcatch.detail#">
    <!--- Remove uploaded file on DB failure --->
    <cfif structKeyExists(variables, "uploadedPath") AND fileExists(expandPath('/uploads/' & uploadedPath))>
        <cffile action="delete" file="#expandPath('/uploads/' & uploadedPath)#">
    </cfif>
    <cfset request.userMessage = "Could not save your product. Try again later.">
</cfcatch>

<cfcatch type="any">
    <cftransaction action="rollback">
    <cflog file="app" text="Unhandled error: #cfcatch.message#">
    <cfset request.userMessage = "An unexpected error occurred.">
</cfcatch>

<cffinally>
    <!--- Additional cleanup or metrics --->
</cffinally>

This pattern ensures that Validation errors, database failures, and unexpected exceptions are each handled appropriately, and that partial work (such as an uploaded file) doesn’t remain after a failure.

See also  What Is ColdFusion Admin API?

Use Cases

Database Operations

  • Wrap queries and stored procedures to catch timeouts or constraint violations.
  • Combine with cftransaction to consistently roll back on errors.
  • Log query parameters (sanitized) for Troubleshooting.

File I/O

  • Handle file not found, permission errors, and path issues with cffile operations.
  • Delete temporary files inside or always clean up in .

External Services and APIs

  • Use cfhttp for REST calls inside .
  • Catch timeouts, 4xx/5xx HTTP status codes, and JSON parsing errors.
  • Retry transient failures (with backoff) and surface friendly messages.

Data Validation and Business Rules

  • Throw custom exceptions with cfthrow when rules fail.
  • Catch with a specific type like type=”validation” to show user feedback.

Best practices

  • Prefer specific catch types before type=”any” to avoid hiding real issues.
  • Always log critical information: cfcatch.message, cfcatch.detail, cfcatch.stackTrace (where available), and cfcatch.tagContext.
  • Use for guaranteed cleanup (closing resources, unlocking, clearing temp data).
  • Don’t swallow exceptions silently. If you handle it, either provide a user message, log it, or rethrow with cfthrow.
  • Use cftransaction around related DB operations and roll back on exceptions.
  • Sanitize logs: avoid logging sensitive data (passwords, tokens).
  • Keep try blocks small. Narrow scope improves clarity and reduces accidental masking.
  • For application-wide errors, use Application.cfc onError() or cferror alongside local try/catch.
  • When integrating with components, document which methods throw which types and handle them at call sites.

Comparison With Other ColdFusion Error-Handling Features

Feature Scope When to Use Notes
CFTRY/CFCATCH/CFFINALLY Local block Fine-grained handling around risky code Most common pattern; supports typed catches
Application.cfc onError App-wide Centralized catch for uncaught errors Great for logging, alerts, custom responses
CFERROR Request or site level Legacy/global error pages Useful fallback; less flexible than try/catch
Server error templates Server-level Last-resort user-friendly pages Not app-specific; minimal context
See also  What Is ColdFusion Enterprise Edition?

Key takeaway: Use CFTRY/CFCATCH for precise, local handling; fall back to Application.cfc or cferror to catch what slips through.


Advanced Tips and Patterns

Rethrowing and Custom Exceptions

  • Use cfthrow inside a to rethrow with more context.
  • Create custom types (e.g., type=”validation” or type=”billing.PaymentDeclined”) to structure your error taxonomy.

Observability and Alerting

  • Include request IDs, user IDs, or correlation IDs in logs to cross-reference across systems.
  • Consider email or webhook alerts on critical exceptions.

Performance Considerations

  • Exceptions are relatively expensive. Avoid using try/catch to control normal flow; reserve for exceptional conditions.
  • Keep the risky code minimal within the try block.

Working With Lucee vs. Adobe ColdFusion

  • Both support try/catch/finally, but certain cfcatch struct keys and exception types can differ.
  • Test behavior in your target engine and version; consult release notes for changes in exception structures.

Key Points

  • CFTRY and CFCATCH provide structured, typed exception handling in CFML.
  • Add CFFINALLY to guarantee cleanup.
  • Catch the most specific types first, then fall back to type=”any”.
  • Combine with cftransaction, cflog, and cfthrow for robust Error handling.
  • Use Application.cfc onError or cferror for global safety nets.

FAQ

What information is available inside cfcatch?

The cfcatch variable is a struct that typically includes keys like message, detail, type, tagContext, errorCode, and sometimes stackTrace. Availability depends on the CFML engine and the error type.

How do I catch multiple types differently?

Add multiple blocks under the same , each with a different type, ordered from most specific to least specific. For example, database, then Security, then any.

When should I use cferror or Application.cfc onError instead of cftry/cfcatch?

Use cftry/cfcatch for local, fine-grained handling around code that might fail. Use Application.cfc onError or cferror for uncaught exceptions or to provide centralized logging and user-friendly error pages.

Is cffinally required?

No, but it is recommended. Use when you need to guarantee resource cleanup (files, locks, temp data), regardless of success or failure.

About the author

Aaron Longnion

Aaron Longnion

Hey there! I'm Aaron Longnion — an Internet technologist, web software engineer, and ColdFusion expert with more than 24 years of experience. Over the years, I've had the privilege of working with some of the most exciting and fast-growing companies out there, including lynda.com, HomeAway, landsofamerica.com (CoStar Group), and Adobe.com.

I'm a full-stack developer at heart, but what really drives me is designing and building internet architectures that are highly scalable, cost-effective, and fault-tolerant — solutions built to handle rapid growth and stay ahead of the curve.