DevLearningTools

MODULE 12 · LESSON 08

Debugging

Inspecting what's actually happening with cfdump/writeDump, halting execution exactly where something looks wrong with cfabort, real engine differences between Adobe and Lucee, and where ColdFusion's line debugger fits in.

New lessons are added one at a time as the course gets built out — a graded quiz for each lesson is still on the way.

cflog records what happened after the fact. Debugging is about inspecting what's happening right now: cfdump (writeDump in CFScript) shows the full contents of a variable, and cfabort stops execution exactly where something looks wrong, so a page doesn't keep running past the point that actually matters.

Learning Objectives

After completing this lesson, you'll be able to:

  • Inspect a variable's full contents with cfdump/writeDump.
  • Combine cfdump and cfabort to halt execution exactly where something looks wrong.
  • Recognize the real engine differences between Adobe's and Lucee's dump and abort behavior.

How Debugging Fits In

Something Looks Wrong

cfdump the Suspect Variable

cfabort — Stop Right There

Inspect the Output, Fix It

A Basic Dump

Tag Syntax
<cfdump var="#userProfile#" label="userProfile">
CFScript
writeDump(var = userProfile, label = "userProfile");

cfdump / writeDump's Attributes

AttributeMeaning
varThe variable to display (required)
outputWhere it goes: browser (default), console, or a file path
formathtml (default) or text
labelA header shown above the dump output
expandWhether nested structures start expanded (default) or collapsed
topHow many rows or nesting levels to show
show / hideLimit the dump to specific keys/columns, or exclude specific ones
keysFor a structure, how many keys to display
showUDFsWhether to include user-defined functions in the output
abortWhen true, stops the request immediately after the dump renders
NOTE

abort=true on cfdump itself is a genuinely useful shortcut, it dumps the variable and halts in one line, without a separate cfabort tag.

A Real Example: Dumping an Exception, Then Halting

This is the pattern from earlier in this module put to direct use during development: catch the exception, dump its full contents to see exactly what it is, then stop before anything downstream runs with bad data.

Tag Syntax
<cftry>
    <cfset firstName = userService.getUserById(1).getFirstName()>
    <cfcatch type="any">
        <cfdump var="#cfcatch#">
        <cfabort>
    </cfcatch>
</cftry>
CFScript
try {
    firstName = userService.getUserById(1).getFirstName();
} catch (any e) {
    writeDump(e);
    abort;
}

cfabort's Attributes

AttributeMeaning
showErrorAn error message shown on the standard CFML error page (or routed to a cferror page, if one is defined) when cfabort executes
NOTE

cfabort has both a tag form (<cfabort>) and a script form (abort;). It triggers Application.cfc's onAbort method instead of onRequestEnd.

Real Engine Differences

AspectAdobeLucee
dump format optionshtml or texthtml, text, classic, or simple — more choices for the rendered output style
dump destinationsbrowser, console, or a file pathAdds a debug output option alongside browser, console, or a filename
abort scopeNot documented as configurableA type attribute controls whether abort stops the whole request or just the current page (request by default)
abort inside a function with output=falseNot a documented concernSince Lucee 5.3, function output isn't buffered by default, so abort inside a function may not behave as expected unless this.bufferOutput=true is set
NOTE

The Lucee buffering caveat is a real gotcha worth knowing before relying on abort inside a function that has output=false set.

Beyond cfdump and cfabort: Line Debugging

Adobe ColdFusion also supports step-through line debugging from an IDE like ColdFusion Builder or Eclipse. It's enabled in the ColdFusion Administrator under Debugging & Logging > Debugger Settings (Allow Line Debugging), with a dedicated debugger port and a maximum number of concurrent sessions. It's a separate, IDE-driven workflow from cfdump/cfabort, worth knowing exists but outside the scope of code-level debugging covered here.

Common Beginner Mistakes

Leaving a cfdump call in production code

A dump can expose sensitive data (passwords, tokens, full session contents) directly in the page output. Gate debug dumps behind an environment check, or remove them before shipping.

Dumping a structure that contains sensitive fields without using hide

hide lets specific keys be excluded from the output, useful for dumping something like a user record without exposing a password hash or API key alongside everything else.

Assuming abort inside a Lucee function always stops execution the same way it would on a page

Since Lucee 5.3, function output isn't buffered by default when output=false, meaning abort inside such a function may not behave as expected unless this.bufferOutput=true is configured.

Not knowing about cfdump's own abort attribute

abort=true on cfdump itself dumps the variable and halts the request in one line, a separate cfabort tag isn't needed just to stop right after a dump.

Best Practices

  • Gate debug dumps behind an environment check, or remove them entirely before deploying to production.
  • Use hide to redact sensitive fields when dumping a structure that contains them.
  • Reach for output="console" during development to avoid a large dump taking over the rendered page.
  • Combine cfdump and cfabort (or cfdump's own abort attribute) to stop exactly at the point something looks wrong, rather than letting the request continue on bad data.

Interview Questions

What's the difference between cfdump and cfabort?

cfdump displays a variable's full contents for inspection. cfabort stops the request at that point, returning only what was processed before it. cfdump's own abort attribute can do both in one line.

Why is leaving cfdump calls in production code a real risk?

A dump can expose sensitive data, like a password hash, token, or full session contents, directly in the page output where anyone viewing it could see it.

What does cfabort trigger in Application.cfc, and what does it skip?

It invokes onAbort instead of onRequestEnd.

What's a real Lucee-specific gotcha with abort inside a function?

Since Lucee 5.3, function output isn't buffered by default when output=false, so abort inside such a function may not behave as expected unless this.bufferOutput=true is set.

Summary

In this lesson, you inspected variables with cfdump/writeDump, combined it with cfabort to halt execution exactly where something looks wrong, covered cfabort's real behavior (triggering onAbort, not onRequestEnd), the real engine differences between Adobe and Lucee's dump and abort implementations, and where IDE-based line debugging fits in beyond code-level tools.

What's Next?

This wraps up error handling and debugging. The next module moves into web development: building HTML forms, validating submitted data, and working with URL parameters.