Title: Exception Handling
1- Exception Handling
- MDCFUG 6/12/2007
David Lakein Programmer / Analyst TeraTech Inc.
2About Me
- Application Developer at TeraTech since 1998
- Working in ColdFusion since 1999, CF4.01
- Certified Advanced CF7 Developer
3Whats wrong with this picture?
4The Problem
- Too much info gets shown to users
- Embarrassing
- Could be security hazard
- Site admins/developers need notification, enough
useful debugging info to find the error and be
able to fix - Users wont send it to you, and you dont want
them seeing it anyway!
5What this presentation will cover
- Different types of errors
- Language features used to catch and handle
- Overview of properties
- Suggestions for usage
- Creating a simple customizable general error
handler
6What this will not cover
- Wont cover all details and properties of cfcatch
and error object - Check out the references at the end
7Types of errors
- Exception Error that doesnt allow the request
to continue. - You can catch the error, and CF gives you a
structure with error details. - Types/examples of errors
- Parse/Compile error malformed CF tags
- Syntax error missing property
- Runtime wont be found until code executes
- Validation server-side form validation
- System connection fails
- Request URL that user requested doesnt exist
- Not a CF exception, but CF can handle
- Different from CFs CFError typeRequest
- Logic errors dont directly cause an exception,
but are still wrong
8Error Parse
- ColdFusion first parses the templates, then
compiles into Java. If CF cannot parse the
syntax, there is little useful it can do with it. - If its in the main request page, wont be caught
by CFCatch, CFError, or OnError! - Goes straight to server-wide error handler
- Will be caught properly if parse error happens in
an include (lower level than the error handler)
ltcfif 1 eq 3gt I have no closing cfif tag.
9Error Syntax
- Code can be parsed, but language use is wrong,
which may prevent it from being compiled. - e.g., Missing required attributes or arguments,
invalid parameters
ltcfbadgt CF will say "Unknown tag cfbad.
ColdFusion cannot determine how to process the
tag cfbad because the tag is unknown and not in
any imported tag libraries. The tag name might be
misspelled" lt/cfbadgt
10Error Runtime
- Errors that happen when the code is executing
- This covers most other kinds of code errors
- Error responses from outside CF
- CFHTTP calls
- Database
- CFML errors
- Undefined variables
- CFThrow creating a custom exception type
- CFAbort with showerror attribute
- E.g., Value set in in a variable at runtime is
the wrong type for a function argument, if it has
a type.
11Error Validation
- CF has basic built-in server-side form validation
fields e.g., hidden fields named
fieldname_required or fieldname_type. - If the submitted data fails, CF throws a
Validation error. - Similar feature will be generated by CF7's
CFInput validateAt"onServer" - Depends on the extra hidden form fields submitted
by client
ltinput type"text" name"firstname" /gt ltinput
type"text" name"age" value"Twenty" /gt ltinput
type"hidden name"firstname_required"
value"First name is required."/gt ltbr/gt ltinput
type"hidden name"age_integer" value"Age must
be an integer." /gt
12Error System
- Type of runtime error
- Bad connection to db
- File is missing
13Reducing Details Shown By Default
- Turn off Robust Exception Information to reduce
what gets shown to the user if an error isnt
handled, or if the exception handler fails.
14Where CF Handles Errors
- Server-wide error handler
- Server-wide missing template handler
- HTTP 404 error
- CFError tag
- Catches unhandled errors anywhere after the point
where it is defined - Application.cfc onError event (CF7)
- Application.cfc onMissingTemplate event (CF8, in
public beta) - Local HTTP 404 handler
- CFTry/CFCatch
- Catch errors right around the code they happen
15Server-wide error and 404 handlers
- Missing Template handler URL from root of the
website - HTTP 404 errors
- Browser requests CF page that doesnt exist
webserver passes to ColdFusion to handle. - Site-wide error handler ColdFusion path,
including mappings, from root. - Template that is executed whenever an error is
not handled at the application or code level.
16CFError
- Catches unhandled errors anywhere after the point
where it is defined - Declare anywhere in cfm pages. Should be near the
top of the Application.cfc or Application.cfm - Object named Error error details, stack
trace, location, templates called
17CFError (contd)
- Attributes
- Template CF relative or absolute mapping path to
the error handler template - Type
- Exception (optional) specific type to catch
- Mailto (optional) passes in as error.mailTo
- Type
- TypeException full exception handler.
- TypeRequest errors that fail exception
handler. Limited can only output Error
variables. - TypeValidation CF form validation. Limited
like Request type.
18CFError example
ltcferror type"exception template"exception.cfm
mailTo"dl_at_domain.com"gt
lth1gtExample cferror in Application.cfm, mail to
admin.lt/h1gt lt!--- Undefined variable, will cause
an error ---gt ltcfoutputgtNonExistentVariablelt/cfo
utputgt lth3gtSince we are using cferror
type"Exception", html after the error will not
appear, and html before the error will only
show in Error.GeneratedContent. lt/h3gt
19CFError example (contd)
lt!--- Default address to send to ---gt ltcfset
mailtoadmin_at_domain.com"gt ltcfif
structkeyExists(Error, "mailto") AND
Len(error.Mailto) GT 0gt ltcfset mailto
Error.mailtogt lt/cfifgt ltcfmail servermailserver.d
omain.com" from"admin_at_domain.com"
to"mailto" subject"Error in Example App on
CGI.HTTP_HOST" type"html"gt lth4gtERROR In
page Error.Templatelth4gt ltcfdump var"error"
label"Error object"gt ltcfdump var"cgi"
label"CGI scope"gt lt/cfmailgt ltcfoutputgt lthtmlgtlthea
dgtlttitlegtAn error occurred.lt/titlegt lt/headgt ltbodygt
ltdiv style"background-color cc4400 padding
1em lth3 style"color black"gtSorry, there was
an error. Site admins have been
contacted.lt/h3gt lt/divgt lt/bodygt lt/htmlgtlt/cfoutputgt
20CFError example (contd)
21Application.cfc onError event (CF 7)
- Arguments
- Exception - exception object
- Similar in structure to the CFCatch object you
get with cftry/cfcatch - EventName - string
- Contains Application event name, if error is in
Application.cfc - Otherwise, blank string
- No return value
- You can/should still have a cferror tag in the
declarations section of your Application.cfc
that will run if there is an error in your
OnError event. - Overrides all other error handlers besides
CFCatch - Check limitations in LiveDocs no output if runs
in onApplicationEnd or onSessionEnd events
22Application.cfc onError event Example
ltcffunction name"onError" returnType"void"
output"true"gt ltcfargument name"Exception"
required"true"/gt ltcfargument name"EventName"
type"String" required"true" /gt ltcfoutputgtErr
or caught in Application.cfc, GetCurrentTemplateP
ath() ltbr/gtlt/cfoutputgt ltcfoutputgtEvent name
'Arguments.EventName'lt/brgtlt/cfoutputgt lt!---
ltcfdump var"Arguments" label"Arguments"gt---gt
ltcfdump var"Arguments.Exception"
label"Arguments.EventName
Exception"gt ltcfdump var"CGI"
label"CGI"gt ltcfdump var"variables"
label"variables in application.cfc"gt lt/cffuncti
ongt
23Application.cfc onMissingTemplate event (CF 8,
beta)
- Used as a local application-specific 404 handler
when page specified in URL does not exist. - Arguments targetPage string.
- Return true if handled ok, false if you want to
throw a 404 error. - If there is a Missing Template error handler
defined in CFAdmin, that will catch. - If that is not defined, CF's built-in default 404
handler will run
24Application.cfc onMissingTemplate event (CF 8,
beta) example
- ltcffunction name"onMissingTemplate"gt
- ltcfargument name"targetPage" type"string"
requiredtrue/gt - lt!--- Use a try block to catch errors. ---gt
- ltcftrygt
- lt!--- Log all errors. ---gt
- ltcflog type"error" text"Missing template
Arguments.targetPage"gt - lt!--- Display an error message. ---gt
- ltcfoutputgt
-
- lth3gtArguments.targetPage could not be
found.lt/h2gt - ltpgtYou requested a non-existent ColdFusion
page.ltbr /gt - Please check the URL.lt/pgt
- lt/cfoutputgt
- ltcfreturn true /gt
- lt!--- If an error occurs, return false. ---gt
- ltcfcatchgt
- ltcfreturn false /gt
- lt/cfcatchgt
- lt/cftrygt
25CFTry/CFCatch
- Wrap the CFTry/CFCatch around a block of code,
and it handles errors inside that block - Handles errors locally can show inside the
layout. - Inside the cfcatch tags, you have an object named
cfcatch, contains error properties and related
objects. - You can specify catching certain types only
- Rethrow error (tag CFRETHROW) if you want to send
the error to a higher level.
26CFTry/CFCatch sample
- ltcferror type"exception" template"exception.cfm"
gt - lt!--- any code out here will be handled by the
above exception handler "exception.cfm", - or by the Application.cfc OnError if it exists
---gt - ltcfinclude template"test1.cfm"gt
- ltcftrygt
- lt!--- Any code in here will be handled by these
cfcatch blocks ---gt - ltcfinclude template"test2.cfm"
- ltcfcatch type"Any"gt
- lt!--- Handle the error here ---gt
- lth3gtThere was an error with this operation!lt/h3gt
-
- ltcfdump var"cfcatch label"CFCatch object!"gt
- lt/cfcatchgt
- lt/cftrygt
- lt!--- any code out here will be handled by the
above exception handler "exception.cfm",
27What to do in your error handler
- Log
- CF already logs basic exception info to
exception.log - Could log extra error info to file, one line per
error - New in CF8 there will be built-in Derby
databases all inside the CF service, no
connections to go down. This may allow for
logging other properties than would be doable in
a text log, then provide for easy search
capability. - Email
- HTML formatted email, get a table of all the info
you need - Use a common template
- Pass in settings for CFMail or logging.
- Optionally show debug info for local developers
pass in Debug variable controlled by IP and a URL
var - CAUTION if there is an error in this level, like
DB connection, or email malformed, will throw the
original error to a higher level! - You won't know about the exception in the error
handler.
28What to send
- Scopes error/cfcatch/exception object, cgi
scope, form, other scopes - Simple version cfdump
- Server-wide handler shouldnt have a lot of
moving parts. - If you check specific optional parts of the
error/catch object, check StructKeyExists first! - If you have a more involved template, use
try/catch in that, and do a basic action by
default. Always handle.
29 CFDump
- You may want to write code to parse out the
properties of the error/catch object, instead of
just dumping. - Highlight most important/useful properties at the
top of the email - Potential issue with dumping a CFCatch There may
be an issue with dumping the full object,
depending on server installation, version (6.1) - Error detail message may not be clear also could
include HTML content which you wont want in
there. - Process SQL output, show query more visibly.
30Example 1 CFError included in same file
ltcferror type"exception" template"exception.cfm"
gt lth1gtExample 1 Use cferror in the
templatelt/h1gt lt!--- Undefined variable, will
cause an error ---gt ltcfoutputgtNonExistentVariable
lt/cfoutputgt lth3gtSince we are using cferror
type"Exception", html after the error will not
appear, and html before the error will only
show in Error.GeneratedContent.lt/h3gt
31Example 1 (contd)
lt!--- We should be mailing these details (like
previous CFError example), and showing only a
nice message. ---gt lth1gtException Template Example
1lt/h1gt lth3gtError scopelt/h3gt ltcfdump
var"error" gt lth3gtCGI scopelt/h3gt ltcfdump
var"cgi"gt lth4gtError handled at
ltcfoutputgtGetCurrentTemplatePath()lt/cfoutputgt lt
/h4gt
32Example 2 CFError included in Application.cfm
ltcfsilentgt ltcferror type"exception"
template"exception.cfm"gt lt/cfsilentgt
lth1gtExample 2 Use cferror in the
Application.cfmlt/h1gt lt!--- Undefined variable,
will cause an error ---gt ltcfoutputgtNonExistentVar
iablelt/cfoutputgt lth3gtSince we are using cferror
type"Exception", html after the error will not
appear, and html before the error will only
show in Error.GeneratedContent. lt/h3gt
33Example 2 (contd)
lt!--- We should be mailing these details (like
previous CFError example), and showing only a
nice message. ---gt lth1gtException Template Example
2lt/h1gt ltdiv style"background-color bbbbbb
padding 2em"gt lth3gtError scopelt/h3gt ltcfdump
var"error" gt lth3gtCGI scopelt/h3gt ltcfdump
var"cgi"gt lth4gtError handled at
ltcfoutputgtGetCurrentTemplatePath()lt/cfoutputgt lt
/h4gt lt/divgt
34Example 3 onError event of Application.cfc (CF7
only)
ltcfcomponent name"Application"gt ltcfset
this.name"DLTestFolder"gt ltcferror
type"exception" template"exception.cfm"
gt ltcffunction name"onError" returnType"void"
output"true"gt ltcfargument name"Exception"
required"true /gt ltcfargument name"EventName"
type"String" required"true"/gt ltcfoutputgtError
caught in Application.cfc, GetCurrentTemplatePat
h() ltbr/gtlt/cfoutputgt ltcfoutputgtEvent name
'Arguments.EventName'lt/cfoutputgt ltcfdump
var"Arguments.Exception" label"Arguments.Even
tName Exception"gt ltcfdump var"CGI"
label"CGI"gt lt/cffunctiongt lt/cfcomponentgt
35Example 3 (contd)
lth1gtExample 3 Use OnError in the
Application.cfclt/h1gt lt!--- Undefined variable,
will cause an error ---gt ltcfoutputgtNonExistentVar
iablelt/cfoutputgt lth3gtSince this error is caught
by its Application.cfc OnError event, html
after the error will not appear, BUT html
before the error will output to the browser. lt/h3gt
36Example 4 onMissingTemplate event of
Application.cfc (CF8 only, in beta)
ltcfcomponent name"Application"gt ltcfset
this.name"DLTestFolder"gt ltcffunction
name"onMissingTemplate"gt ltcfargument
name"targetPage" type"string"
required"true"/gt lt!--- Use a try block to
catch errors. ---gt ltcftrygt lt!--- Log
all errors. ---gt ltcflog type"error"
text"Missing template Arguments.targetPage"gt
lt!--- Display an error message. ---gt
ltcfoutputgt lth3gtArguments.targetPage
could not be found.lt/h2gt ltpgtYou
requested a non-existent ColdFusion page.ltbr /gt
Please check the URL.lt/pgt
lt/cfoutputgt ltcfreturn true /gt lt!---
If an error occurs, return false and the default
404 error handler will run. ---gt
ltcfcatchgt ltcfreturn false /gt
lt/cfcatchgt lt/cftrygt lt/cffunctiongt lt/cfcomponen
tgt
37Example 5a, CFTry/CFCatch File error
- Application.cfc, like in example 3
lth1gtExample 5 Try/catch, file errorlt/h1gt lt!---
Wrap the bad code in try/catch ---gt ltcftrygt
lt!--- Code that causes the error ---gt
ltcfinclude template"boogabooga.cfm"gt ltcfcatch
type"any"gt lt!--- If you want to not handle
this here, rethrow this error to the higher
handler. ---gt lt!--- ltcfrethrow gt ---gt
ltcfdump var"cfcatch" label"CFCatch in
Example 5"gt lth4gtError handled at
ltcfoutputgtGetCurrentTemplatePath(),
CFCatchlt/cfoutputgtlt/h4gt lt/cfcatchgt lt/cftrygt lth3gtI
f there was no error in the Catch block, this
should display.lt/h3gt
38Example 5b, CFTry/CFCatch DB error
- Application.cfc like in example 3
lth1gtExample 5 Try/catch - Database
errorlt/h1gt lt!--- Wrap the bad code in try/catch
---gt ltcftrygt lt!--- Code that causes the
error nonexistent table ---gt ltcfquery
name"myquery" datasource"cfdocexamples gt
Select bar FROM foo lt/cfquerygt ltcfcatch
type"any"gt lt!--- If you want to not handle
this here, rethrow this error to the higher
handler. ---gt lt!--- ltcfrethrow gt ---gt
ltcfdump var"cfcatch" label"CFCatch in
Example 5"gt lth4gtError handled at
ltcfoutputgtGetCurrentTemplatePath(),
CFCatchlt/cfoutputgtlt/h4gt lt/cfcatchgt lt/cftrygt lth3gtI
f there was no error in the Catch block, this
should display.lt/h3gt
39Example CFError, break CFMail
- Exception.cfm (like the first CFError example)
. . . . ltcfmail serRRRvermailserver.domain.com"
from"admin_at_domain.com" to"mailto" subjec
t"Error in Example App on CGI.HTTP_HOST" type
"html"gt . . . . .
40Other useful info
- GetCurrentTemplatePath() if you have error
handling templates multiple places, shows exactly
where this error template is. - CGI. HTTP_HOST Which site this is running on
(in subject line) - Other CGI info
41Caveats
- If you have a high-volume site, you may want
another solution than emailing you every time,
especially for errors that each and every visitor
will hit. - If you use CFParam and CFQueryParam on form or
URL values Make sure you handle form validation
before this on the server-side. - Provides for nicer validation messages
- Form value type errors wont clutter your inbox,
distracting from real errors.
42References
- Livedocs
- Handling Errors (chapter) http//livedocs.adobe.
com/coldfusion/7/htmldocs/00001130.htm - How ColdFusion handles errors
http//livedocs.adobe.com/coldfusion/7/htmldocs/00
001135.htm - CFAdministrator Settings page global 404 and
exception handlers http//livedocs.adobe.com/coldf
usion/7/htmldocs/00001705.htm - Application.cfc OnErrorhttp//livedocs.adobe.com/
coldfusion/7/htmldocs/00000697.htm - Quickdocs
- http//cfquickdocs.com/cferror
- http//cfquickdocs.com/cftry
- Other presos
- Mosh Teitelbaum, Feb 2004 http//mdcfug.org/meeti
ngs/AdvancedColdFusionError_Handling.ppt - Google search
- sitelivedocs.adobe.com ColdFusion 7 keywords