The Complete Guide to Adding Error Handling to Your ColdFusion Application

I've done more than a few posts recently about error handling and robust exception information, so I thought I'd write up one blog entry that can serve as a nice guide for folks to bookmark. By using "Complete" in the title, I've also virtually assured that I will forget something critical, so please, send suggestions for what I've missed. Let's get started.

What is the point of this guide? Unless you are a perfect code, there is a chance that your ColdFusion application will have errors in it. The question is - what are you doing with your errors? What was the last error that occurred on your site? If I asked you how many errors your site threw yesterday, could you answer with 100% complete accuracy? I'd be willing to bet most people would say no. Shoot, I know I couldn't answer that. So what do we do to help resolve this issue?

The first thing I want you to do is to create an error. Create a new CFM file named errortest.cfm. Insert one line into it:

<cfoutput>#xfhdshsdhj#</cfoutput>

The point of this template is to create an error. Unless you actually have a variable defined with that ugly name, the template will error out. Upload it to your server and run it with your browser.

One of three things will happen:

1) You will get an error with the full path shown, like below. This shows that you have not added error management to your application, and that you have Enabled Robust Exception information in your ColdFusion Administrator. Stop reading this blog entry, go to your Admin, and disable it. Now. (Please note that this guide is intended for a production machine environment. Obviously you can keep this setting on in development. I do.)

2) You will get an error with no path shown. This is slightly better. It still shows that you haven't added error management to your application though.

3) You get an "error page". By "error page" I mean a page saying that an error occurred, but displayed in your standard site layout, or close to it. That's good. You should still continue to read though as I'm going to discuss things that should normally be in an error handler.

Ok, before going on - delete the page you just uploaded. I'd be willing to bet a good 40-50% of us upload test.cfm type files to our servers and forget to delete them. I've never done that. Really.

So - lets talk error handling now. You have two high level options. The first is to set an error template in the ColdFusion administrator:

If you specify a template here, than ColdFusion will run the template when an error occurs. In general though I wouldn't recommend setting the template here.

Your second option - and what I recommend - is to the handle the errors specifically in your application. How? If you are on an older ColdFusion server and only have access to Application.cfm, then you want to the use the CFERROR tag. You can use these tags in Application.cfc as well, but I recommend onError for that. I'm going to cover both though.

A full description of cferror may be found in the docs. I'm going to give you the Ray Camden quickie guide to it. The cferror basically lets you specify an template to run when a type of error occurs. There are 3 main types of errors it monitors: Exception, Request, and Validation. Forget about validation. Don't use it. Exception is the type of error we are most familiar with. It is what I call the 'basic' error. Request is the more serious error. It can occur when your error handler itself screws up. I call this the "Oh S***" error (seriously). It has special restrictions on it I'll discuss in a second. First though, let's look at the syntax you would use in your Application.cfm file:

<cfapplication name="rayrules">

<cferror type="exception" template="error.cfm">
<cferror type="request" template="error_request.cfm">

As you can see - it's pretty simple stuff. I basically said - for the Exception (again, think 'normal' error), run error.cfm. For the Oh Crap error, run error_request.cfm.

If you run any CFM again - you will immediately get an error stating that these files do not exist. You should create blank ones for the time being.

Now for the details. The error.cfm template is a normal CFM page. But it has access to a special variable: ERROR. This variable is a structure that contains a lot of information about the error. What you get there will also depend on the error. SQL errors for example will have different values in the structure than a simple runtime error. Let's just do a quick dump.

<cfdump var="#error#">

If you run your error test again (you may have to reupload it if you deleted it like I suggested, just don't forget to remove it later!), you will see something like this:

I'm not going to list every field - again, check the cferror syntax doc for that. The item you will most care about normal is cferror.message. This is the simplest representation of the error and will be most useful for logging. The diagnostics value gives more detail including a line number which is handy during development.

So what now? Well first off - you probably don't want your public site showing a dump. Let's begin by outputting a nice message to the user. Here is the new version of error.cfm:

We are so sorry. Something went wrong. We are working on it now.

Obviously you can mark that up with nice HTML, use your custom tag layout wrapper, etc. This handles letting the user know something bad happened. At bare minimum, this is better than showing naked errors to the user, but we should do something with the error. I recommend two things.

Log the error. For some odd reason, ColdFusion will nicely log an unhandled error, but will not log a handled error. I believe Blue Dragon logs the error anyway. Since ColdFusion won't log it, we should:

<cflog file="myapperrorlog" text="#error.message# - #error.diagnostics#">

Note that I've specified the message and diagnostics variable. This is a bit of a duplication since diagnostics information will have the same information as message, but I like the shortness of the message value. You could log more than this obviously, but since this is a log file, we don't want to overdue it here.

THe next thing we should do is email the error. This is something I've covered before on the blog, so some of you may know my feelings on this already, but what I typically do is email me the entire error structure. I also include other structures so I can see what else was going on:

<cfsavecontent variable="errortext">
<cfoutput>
An error occurred: http://#cgi.server_name##cgi.script_name#?#cgi.query_string#<br />
Time: #dateFormat(now(), "short")# #timeFormat(now(), "short")#<br />

<cfdump var="#error#" label="Error">
<cfdump var="#form#" label="Form">
<cfdump var="#url#" label="URL">

</cfoutput>
</cfsavecontent>


<cfmail to="bugs@myproject.com" from="root@myproject.com" subject="Error: #error.message#" type="html">
   #errortext#
</cfmail>

I create my message within a cfsavecontent (more on why in a second), and then mail it. Don't forget the type=html. Now as you can guess, this creates a pretty big email. If you get a 1000 of these, you will be suffering, but consider it incentive to fix the darn bug ASAP. You could also add a dump of the session scope if you wanted, or CGI. Basically, it is better to send more information then you need then to be wanting for more. Having all this detail gives you a better idea of what is going on when the error occurred.

So why the cfsavecontent? One trick I'll often do is to skip the email if I'm currently logged in as an admin on the site. I'll do a quick check, and if I'm an admin, I'll display the error on screen. This lets me see the error more quickly than waiting for an email.

So all together now, here is the error.cfm file:

We are so sorry. Something went wrong. We are working on it now.

<cflog file="myapperrorlog" text="#error.message# - #error.diagnostics#">

<cfsavecontent variable="errortext">
<cfoutput>
An error occurred: http://#cgi.server_name##cgi.script_name#?#cgi.query_string#<br />
Time: #dateFormat(now(), "short")# #timeFormat(now(), "short")#<br />

<cfdump var="#error#" label="Error">
<cfdump var="#form#" label="Form">
<cfdump var="#url#" label="URL">

</cfoutput>
</cfsavecontent>


<cfmail to="bugs@myproject.com" from="root@myproject.com" subject="Error: #error.message#" type="html">
   #errortext#
</cfmail>

Now for fun, try modifying your error.cfm. Change the first cfdump tag to a cfpoo tag. If you rerun your template, you will see a blank page. Remember that we created a blank error_request.cfm file earlier? This is what is running now. Basically, ColdFusion has noticed that we had an error, and then our error management had an error, and it's thrown it's hands up in the air and given up. We are now in the request template. The request template has special rules - the most important being - no CFML. That's right - you can't cflog. You can't email the error. You can - however - output error variables. You don't use cfoutput, you just include them. Consider this sample:

This went wrong: #error.diagnostics#

This will display:

This went wrong: Unknown tag: cfpoo. ColdFusion cannot determine how to process the tag cfpoo because the tag is unknown and not in any imported tag libraries. The tag name might be misspelled. The error occurred on line -1.

That's all you can do really. But guess what - I wouldn't do that. Remember - we don't want to reveal any sensitive information to our users, including what caused an error. So what do I recommend?

Go to your site and view source. This will give you the HTML result of one of your pages. Find the content and replace it with a "We're sorry" type message like we used in error.cfm. Then save that HTML. Basically you are creating a static page. This means that if you change your layout, you have to regenerate your error_request.cfm page. Of course, you could just not use any layout at all, but most people want their pages to have a standard look and feel.

Unfortunately, nothing is logged when this error happens. So what can you do? One thing to consider is checking the web server log files to see when the file is run. If you see it running often, then double check your error.cfm file for possible errors. If worse comes to worse, temporarily wrap your error.cfm itself in a try/catch and see what shows up when you dump cfcatch. I'm open to suggestions here - but there is a reason they (ok, I) call this the "Oh Crap" error.

Ok, so I've covered quite a bit of information here, but it applies to Application.cfm and CFERROR. What if you are using Application.cfc? Well one thing to remember is that you can just as easily put CFERROR tags inside your Application.cfc file. That is allowed, and I've done that before. But what if you want to use the onError method?

In general - a lot of what I said about the Exception type for CFERROR applies here. You want to present a nice message to your user. You want to log the error. You want to email the error to yourself. But there are some subtle differences.

Consider this very simple onError:

<cffunction name="onError" returnType="void" output="true">
   <cfargument name="exception" required="true">
   <cfargument name="eventname" type="string" required="true">
   <cfdump var="#arguments#"><cfabort>
</cffunction>

All I've done here is dump all the arguments sent in. Now go back to your error file (the one you made to throw errors) and change it to this:

<h1>Hellow World</h1>
<cfoutput>#xfhdshsdhj#</cfoutput>

Run it in your browser, and you will see this:

Notice that the HTML before the error is displayed in the browser. If we had used a nice error message instead of the dump, the user would see both. This can result in oddly formatted pages. What you can do instead is simply handle the error and cflocate to the a nicer page:

<cffunction name="onError" returnType="void" output="true">
   <cfargument name="exception" required="true">
   <cfargument name="eventname" type="string" required="true">
   <cfset var errortext = "">

   <cflog file="myapperrorlog" text="#arguments.exception.message#">
   
   <cfsavecontent variable="errortext">
   <cfoutput>
   An error occurred: http://#cgi.server_name##cgi.script_name#?#cgi.query_string#<br />
   Time: #dateFormat(now(), "short")# #timeFormat(now(), "short")#<br />
   
   <cfdump var="#arguments.exception#" label="Error">
   <cfdump var="#form#" label="Form">
   <cfdump var="#url#" label="URL">
   
   </cfoutput>
   </cfsavecontent>
   
   <cfmail to="bugs@myproject.com" from="root@myproject.com" subject="Error: #arguments.exception.message#" type="html">
      #errortext#
   </cfmail>
   
   <cflocation url="error.cfm">
   
</cffunction>

All I did was take the code from my original error.cfm file and place it in here. The Exception argument here looks a bit different. No diagnostics key. So I just logged the message for now. My error.cfm file now only contains the message:

We are so sorry. Something went wrong. We are working on it now.

Lets recap:

  • Do a quick test to figure out how your application responds to errors.
  • If robust exeception information is displayed, turn it off.
  • Use CFERROR or onError to handle errors.
  • Do your own logging, and email yourself a detailed report.

I hope you find this guide useful, and please let me know how I can improve it.

Comments

existdissolve's Gravatar Ray--

Thanks so much for taking the time to post this. I have been looking for something exactly like this for a while now, and it has helped to provide a context for attacking the error-handling issue that is still daunting for a relatively new CF developer such as myself.

Thanks for all that you do!
# Posted By existdissolve | 12/5/07 3:28 PM
david buhler's Gravatar For those of us using CF for Flex apps...

...do these two dumps need to be prefaced with "StructKeyExists":

<cfdump var="#form#" label="Form">
<cfdump var="#url#" label="URL">

?
# Posted By david buhler | 12/5/07 4:07 PM
Michael Sharman's Gravatar Of course if you have an error in your onError() the same thing will happen with your 'exception' error in the Application.cfm example.

In which case you could use either methods shown above, those being a global error template in CF Admin or a 'request/oh crap' cferror in onRequestStart()

Nice post Ray
# Posted By Michael Sharman | 12/5/07 4:19 PM
Bruce's Gravatar Ray - Thanks for this very complete post about error handling. I used this type of process throughout my websites and it has help me find many "bugs" once I release an appliation to production.

I've been using cfdump in the email that goes out when an error occurs as you illustrate in your Application.cfc code above.

One issue that has always bothered me (mainly because I'm AR) is the extra output in the email that cfdump causes. All the text for the javascript functions that control toggling just get dumped into the email's body. All I want to have in my email body are the contents of the structures (Exception, Form, Session, CGI, etc).

I've tried using cfloop with collection = but the problem is that some of the structures contain complex elements (arrays, another structure) as values so the cfloop collection = fails.

This cfdump issue actually caused me a problem with one of my email clients. That POP3 email client would not display the output from cfdump because with the extra javascript code text outputted the HTML for the email body was not well formed. So I got just part of the error message and no data from the structures.

So if anyone has a good replacement for cfdump to output the complete contents of the structures (Exception, Form, Session, CGI) in a manner that will display correctly in an HTML formatted email, I'd love to hear about it.
# Posted By Bruce | 12/5/07 5:10 PM
Raymond Camden's Gravatar Bruce, have you ever tried this:

<cfdump var="#application#" format="text">

Specifically, format=.
# Posted By Raymond Camden | 12/5/07 5:16 PM
Ryan Heldt's Gravatar Nice post. For our production servers, we do something very similar, but add a couple twists. First, all messages get sent to a common e-mail address (errors@yourcompany.com), which through filters on the mail server we can send a copy to the developer(s) responsible for that site. Those same messages also get pulled into a database (via a scheduled script). The messages can then be searched by site because we include the domain name in the subject line. On the error page itself, we include a reference number - I believe it's the first part of a UUID. Then if a customer happens to get an error, we can get them to tell us that reference code and (using our error database, which has a front-end) we can pull up their error. Overall, we've used this for a few months now, and it's been very helpful.
# Posted By Ryan Heldt | 12/5/07 5:32 PM
david buhler's Gravatar I looked up the attributes for cfdump and the default "format" is listed as 'text'. However, that's not the case.

<!--- outputs as text--->
<cfdump var="#cgi#" format="text">
vs
<!--- outputs as HTML --->
<cfdump var="#cgi#">

I posted a bug with Adobe.

The "format" attribute should be a killer way to get detailed errors on the mobile phone (at last!).
# Posted By david buhler | 12/5/07 5:35 PM
Bruce's Gravatar Ray and others - I'd love to use cfdump's format attribute but unfortunately we've not yet moved our production servers to ColdFusion 8, they are still using CF 7.
# Posted By Bruce | 12/5/07 7:41 PM
Gualtiero Sappa's Gravatar Thanks, this post it's very clear and complete.
We do something similar on our production server and this is very useful to notify us errors in real time and to provide a better look & feel to error pages.
# Posted By Gualtiero Sappa | 12/6/07 7:28 AM
K2's Gravatar Ray,

Great article, thanks. I wanted to print it but found no good way to do so. Do you have a printer-friendly feature that is not turned on? Would be awesome to be able to print these in a printer-friendly way.

k2
# Posted By K2 | 12/6/07 8:46 AM
Raymond Camden's Gravatar I disabled printing when I went to the new design. I was having issues w/ search engines running the print form and running up the RAM on the box.
# Posted By Raymond Camden | 12/6/07 9:20 AM
Raymond Camden's Gravatar You can download the PDF now via the download link above.
# Posted By Raymond Camden | 12/6/07 9:27 AM
CoolJJ's Gravatar @David Buhler
It looks like the format option is supposed to be used with the output attribute. That is when it defaults to text.

@Bruce
I imagine you could write a more complex error.cfm template and then just do a test on each collection item in your cfloop to determine its type and then handle the output appropriatly via the isSimpleValue(), isArray(), isStruct(), isXML() functions.

CoolJJ
# Posted By CoolJJ | 12/6/07 9:58 AM
franz s.fsc's Gravatar Ray,

Nice and helpful post. If i implement it on MX7 the whole mail is visible on the page and all cf code shows on view source?
what am i missing?
# Posted By franz s.fsc | 12/6/07 10:01 AM
Raymond Camden's Gravatar @CoolJJ - Format can be used w/o output, it just defaults to output=html.

@Franz - so if you remember, I mentioned there were two types of errors. Exception=You can use CFML, Request=You Can't. Did you only use the Request one? Remember to use 2 different templates.
# Posted By Raymond Camden | 12/6/07 10:14 AM
Franz Schlienger's Gravatar Ray,

I use
<cferror type="exception" template="error.cfm">
<cferror type="request" template="error_request.html">

the x.cfm is online if you want to check. Look at the <cfset x = 1> in the page source.

Thanks franz
# Posted By Franz Schlienger | 12/6/07 10:22 AM
Raymond Camden's Gravatar I went to your web site (hey, how about a warning next time ;), went to x.cfm, and ended up on anice error page w/ no CFML code in it.
# Posted By Raymond Camden | 12/6/07 10:29 AM
Franz Schlienger's Gravatar Ray,

I changed it back. It shows only on my live but not on the development server. Witch cf server setting could cause it?

Thanks
# Posted By Franz Schlienger | 12/6/07 10:49 AM
K2's Gravatar Thanks much for the PDF.

K2
# Posted By K2 | 12/6/07 10:50 AM
Rick Smith's Gravatar yep... another thanks for the PDF!
# Posted By Rick Smith | 12/6/07 10:53 AM
Raymond Camden's Gravatar Not quite sure I get you Franz. Again, if you used 2 cferror tags, ensure the templates are pointing right. The Exception one points to the template w/ CFML in it. The request one points to the one with no cfml in it.
# Posted By Raymond Camden | 12/6/07 10:56 AM
K2's Gravatar I'm implementing your CFC method above. But, how do I trap and handle Request and validation errors in this way without using cferror? Is there a way or am I missing something?
# Posted By K2 | 12/6/07 11:02 AM
Raymond Camden's Gravatar In order to handle an oh crap error when using onError, I believe you would want to add a cferror tag,type=request. Normal errors should go through onError still.

Try this out. :)
# Posted By Raymond Camden | 12/6/07 11:07 AM
Franz Schlienger's Gravatar Ray,

That's what i have. The first 2 lines of application.cfm are:
<cferror type="exception" template="error.cfm">
<cferror type="request" template="error_request.html">
# Posted By Franz Schlienger | 12/6/07 11:09 AM
Raymond Camden's Gravatar And when you hit x.cfm, you end up on error.cfm? With CFML showing up?
# Posted By Raymond Camden | 12/6/07 11:13 AM
K2's Gravatar Ray,

How do I go about creating a Request or Validation error to test this.
# Posted By K2 | 12/6/07 12:05 PM
Raymond Camden's Gravatar k2: A request error is the Oh Crap error. You can force this by making your exception error itself throw an error.

Don't worry about validation errors. They are used when you use CF's built in form checking, which no one uses, and no one should use.
# Posted By Raymond Camden | 12/6/07 12:08 PM
K2's Gravatar Thanks. I got this working, but with one problem. My Request Error page displays #error.message# instead of the actual error. I just found out that #error.message# is not available on a request error. Thanks CFQuickDocs.

The function:
<code>
<cffunction name="onError" returntype="void" output="true">
<cfargument name="Exception" required="true">
<cfargument name="EventName" type="string" required="true">
<cferror type="request" template="error/RequestErrorDetail.cfm">
<cfinclude template="error/ErrorDetail.cfm">
</cffunction>
</code>

This does work, but I find it much more useful to error trap the exception error page this way.

<code>
<cffunction name="onError" returntype="void" output="true">
<cfargument name="Exception" required="true">
<cfargument name="EventName" type="string" required="true">
<cftry>
<cfinclude template="error/ErrorDetail.cfm">
<cfcatch type="any">
<cfdump var="cfcatch">
</cfcatch>
</cftry>
</cffunction>
</code>

This way I can email the request error (or any other error the 'error' page generates) using the cfcatch scope or do whatever I want with it. Is there a problem doing it this way?
# Posted By K2 | 12/6/07 12:39 PM
Jason Brookins's Gravatar @Ray:

I'm still a bit cloudy on how to incorporate handling your "oh, crap" error into the onError in Application.cfc. Do you have a quick version of the onError function that you can post to show how you handle both?
# Posted By Jason Brookins | 12/6/07 12:43 PM
Raymond Camden's Gravatar Try adding <cferror type="request" template="something.cfm"> to your onRequestStart.
# Posted By Raymond Camden | 12/6/07 1:43 PM
Michael White's Gravatar One of my applications makes heavy use of CFDIV, ColdFusion.navigate, etc to update the "content" cfdiv only. cflocation doesn't work well in that situation and when I try to cfinclude I just get a blank screen instead of my friendly error message and links to get back. I tried to just use cfset ColdFusion.navigate('/errors/error.cfm','content') but application.cfc onerror function doesn't know what to do with that. can you help straighten out my thinking?
# Posted By Michael White | 12/7/07 5:39 PM
Niall's Gravatar Hi Ray,
I have implemented the error handling code in my Application.cfc using the onError() method and all works fine except for the <cferror> tag in the onRequestStart() method to trap the request error.

I have included my Application.cfc for reference:

<cfcomponent output="false">

   <cfset this.name = "mytestportal">
   <cfset this.applicationTimeout = createTimeSpan(0,0,20,0)>
   <cfset this.clientManagement = true>
   <cfset this.clientStorage = "cookie">
   <cfset this.loginStorage = "session">
   <cfset this.sessionManagement = true>
   <cfset this.sessionTimeout = createTimeSpan(0,0,20,0)>
   
   <cffunction name="onApplicationStart" returnType="boolean" output="false">
      <cfreturn true>
   </cffunction>
   
   <cffunction name="onApplicationEnd" returnType="void" output="false">
      <cfargument name="applicationScope" required="true">
   </cffunction>
   
   <cffunction name="onRequestStart" returnType="boolean" output="false">
      <cfargument name="thePage" type="string" required="true">      
      <cferror type="request" template="dspErrorRequest.cfm">
      <cfreturn true>
   </cffunction>
   
   <cffunction name="onRequest" returnType="void">
      <cfargument name="thePage" type="string" required="true">      
      <cfinclude template="#arguments.thePage#">
   </cffunction>
   
   <cffunction name="onRequestEnd" returnType="void" output="true">
      <cfargument name="thePage" type="string" required="true">      
   </cffunction>
   
   <cffunction name="onError" returnType="void" output="false">
      <cfargument name="exception" required="true">
      <cfargument name="eventname" type="string" required="true">
      <cfset var errortext = "" />
      <cfset var mailToAddr = "developersEmail@developers.com" />
      <cfset var mailFromAddr = "applicationEmail@appDomain.com" />
      
      <!---
         IF DEVELOPMENT, SIMPLY USE THIS...NO NEED TO SEND EMAILS!
         <cfdump var="#arguments#"/><cfabort/>
      --->
      <cflog file="#this.name#" text="#ARGUMENTS.exception.message# - #ARGUMENTS.exception.RootCause.Message#" />

      <!--- BUILD THE EMAIL CONTENT --->
      <cfsavecontent variable="errorText">
         <cfoutput>
            An error occurred: http://#cgi.server_name##cgi.script_name#?#cgi.que... />
            Time: #dateFormat(now(), "short")# #timeFormat(now(), "short")#<br />
            
            <cfdump var="#ARGUMENTS.exception#" label="Error">
            <cfdump var="#FORM#" label="FORM">
            <cfdump var="#URL#" label="URL">
            <cfdump var="#SESSION#" label="SESSION">
            <cfdump var="#CGI#" label="CGI">
         </cfoutput>
      </cfsavecontent>

      <!--- E-MAIL THE ERROR TO THE DEVELOPER(S) --->
      <cfmail to="#mailToAddr#" from="#mailFromAddr#" subject="Error: #ARGUMENTS.exception.message#" type="html">
         #errorText#
      </cfmail>

      <cflocation url="dspError.cfm">
   </cffunction>
   
   <cffunction name="onSessionStart" returnType="void" output="false">
   </cffunction>
   
   <cffunction name="onSessionEnd" returnType="void" output="false">
      <cfargument name="sessionScope" type="struct" required="true">
      <cfargument name="appScope" type="struct" required="false">
   </cffunction>
   
</cfcomponent>

When I added an invalid CFML tag in my error handler page:
<cfpoo >
kjhgjhg
</cfpoo>

I simply get the standard coldfusion error message:
A tag starting with 'CF' has been detected. This tag is not supported by this version of ColdFusion. Please verify your typo and try again.

Is there something I'm doing wrong or can you confirm the exact method for trapping these coldfusion errors, if possible?

Thanks!
# Posted By Niall | 12/7/07 7:03 PM
Michael White's Gravatar cfinclude seems to work if I change the output attribute to true on the onError function. but if output is false, i get nothing. That only confuses me because I have a cfinclude for a login form in the onRequestStart method and that worked. I thought I never put output=true on any of my cfc methods but I looked again and the onRequestStart method was also output=true. problem solved?
# Posted By Michael White | 12/8/07 10:52 AM
Raymond Camden's Gravatar output=false is indeed generally wanted. I wouldn't use it. You mentioned when you made use of cflocation, stuff in cfdiv, etc, didn't work. That isn't surprising if the error is in ajax. I'll have to test this. One possible idea - make all your ajax requests go to urls with ajax_ in them. If you see that the error is here, then use cfinclude as opposed to cflocation.
# Posted By Raymond Camden | 12/8/07 10:57 AM
Michael White's Gravatar what I mean by cflocation not working is that you can't direct the output to a cfdiv, it has to replace the whole page, right? with a ColdFusion.navigate() I could put the error message in the 'content' cfdiv (so I tried all sorts of ways to force a ColdFusion.navigate and couldn't do it. I didn't see any Event on cfmail I could use to fire it off either.
# Posted By Michael White | 12/8/07 11:11 AM
Raymond Camden's Gravatar Let me make sure I'm reading you right. You are talking about how to handle an error when the error occurs inside something loaded by cfdiv/cfwindow/cfpod, right?
# Posted By Raymond Camden | 12/8/07 11:15 AM
Michael White's Gravatar in my application there is an index.cfm and EVERYTHING is loaded into a cfdiv or cfwindow. when there is an error my first thought was to send the friendly error to the 'content' cfdiv but opening up a new cfwindow would work as well, maybe better.
# Posted By Michael White | 12/8/07 11:18 AM
Raymond Camden's Gravatar Hmm. That seems a bit.... odd. But I'll ignore that. So I can see how cflocation won't work in the result of a cfdiv/cfwindow. In that case you want to either cfinclude or cfoutput a result of some sort. The issue though is that you could possibly still have partial content, which is why I suggested cflocation in general. Ie, partial content then your error message. You know, CF's Ajax support has a setGlobalErrorHandler function. You could try that. In that case, you don't handle the error, but let it occur, and then use the JS function to handle it. You lose nice email reports though. You may want to try using onError, mail, log, and then cfthrow to throw a new error which the JS function would trap.
# Posted By Raymond Camden | 12/8/07 11:25 AM
Michael White's Gravatar This is such an important post for a lot of people, I got you an item off your wishlist (80s music CD) in appreciation
# Posted By Michael White | 12/8/07 3:05 PM
Ryan LeTulle's Gravatar Great information.

Thank you Ray.

See you at Sakura. :)
# Posted By Ryan LeTulle | 12/10/07 1:58 PM
Paul Davis's Gravatar Great Article Ray!!

One thing that we have been doing is to clean up the error text into a simple readable email and log format by parsing the error structure, there is still an option to dump if the need is there (our error handler is a component that exists in the application layer and is called from the application.cfc). But normally you can get what you need through a little parsing which I find much easier to digest when coding.

Another thing that we do is check to make sure that things exist before we attempt to email them, for instance I have run into errors where parts of the session simply do not exist or even some of the application layer components, so I've learned to put a isdefined() check on almost anything that get's parsed. If it's not there then it's simply not provided, it's more work but in liue of a huge message it's very useful for us.

Thanks

-Paul-
# Posted By Paul Davis | 12/12/07 11:35 AM
Bruce's Gravatar Paul - if you see my comment above, I'm looking for a good parsing function instead of using cfdump. So if could share your parsing function code that would be great.
# Posted By Bruce | 12/12/07 12:44 PM
David Whiterod's Gravatar Thanks for the post Ray!

Do you know of a way to access the (optional) errorcode and (custom) type cfthrow args from a (CFERROR) error handling page.

It looks like errorcode and type are only available within a cfcatch block and do not bubble up to the cferror page.

Cheers

David
# Posted By David Whiterod | 2/3/08 10:20 PM
Raymond Camden's Gravatar If they don't exist, then I'm not sure what to recommend. I always thought the complete error object was available.
# Posted By Raymond Camden | 2/4/08 9:52 AM
David Whiterod's Gravatar Cheers Ray

On further investigation, I didn't look hard enough.

Within a CFCATCH the errorcode etc is available (top-level) within the cfcatch struct. Once passed to a cferror template the error object is no longer in the top-level of the error struct but available at error.RootCause.

What started to trick me is cfcatch.type will report a custom error type but error.type (even when a custom error is specified) will always be 'coldfusion.runtime.CfErrorWrapper'.

(I'm using CF8,0,0,176276 Enterprise)

Cheers

David
# Posted By David Whiterod | 2/4/08 8:51 PM
Shama's Gravatar I have the same question as posted by Niall above. That is, I have added
<cferror type="request" template="error_request.cfm"> to the onRequestStart() function in Application.cfc but it doesn't seem to catch the error and display the custom template. I still get the standard coldfusion error message. Any help would be greatly appreciated. Thanks!
# Posted By Shama | 2/18/08 3:28 PM
Steve Clifton's Gravatar Great post for error handling, but what about missing template handling? This code does not appear to handle the standard CF error when a page that does not exist is called by the user. Am I doing something wrong?
# Posted By Steve Clifton | 2/18/08 4:28 PM
Raymond Camden's Gravatar I'd just use the onMissingTemplate support in CF8.
# Posted By Raymond Camden | 2/18/08 4:52 PM
Steve Clifton's Gravatar Ray,
Unfortunately we are still running CF7 and plan to do so for a few more months. What is your solution for missing template handling on CF7, cos the setting in CF Administrator simply does not work on boxes hosting more than one site!
Thanks,
Steve
# Posted By Steve Clifton | 2/18/08 5:04 PM
Raymond Camden's Gravatar I don't have a great answer. You can use IIS's check for script existence setting and then handle the 404 that way, but not sure if a solution exists for Apache.
# Posted By Raymond Camden | 2/18/08 5:14 PM
Steven Waters's Gravatar Thanks, this code is very helpful.
# Posted By Steven Waters | 2/20/08 5:41 PM
Niall's Gravatar @Shama
I have implemented a solution for the complete exception and request error handling - just haven't got round to posting it.

If you don't mind - and Ray doesn't mind me using this post for this - you can mail me directly for the source code to n.odoherty [at] niallodoherty [dot] com

These are in no way complete - but were intended to be used as a starting point for implemnting in new applications. Therefore there will be "some" changes required.
# Posted By Niall | 2/23/08 5:51 PM
Raymond Camden's Gravatar Niall, non-commercial offers like these are fine with me.
# Posted By Raymond Camden | 2/24/08 2:51 PM
mgwalk's Gravatar the error on line -1 error can be fixed here
http://kb.adobe.com/selfservice/viewContent.do?ext...
# Posted By mgwalk | 3/25/08 12:59 PM
xavier's Gravatar I thouhgt I will pose this question here as it is related to error handling. My company recently moved a site which was running on ColdFusion 5 and SQL 2000 to new servers (CF 8 and SQL 2005). A new error handling method was also introduced. Now, I understand this is not the recommended way of error handling, but it was something that was thrown in at the last minute. This method works by adding a Cftry and cfcatch pair around all requests - this code is added to the index page which includes all the other pages. The cfcatch will write to database and email us and also display a friendly error message to the user.

Now, with the new servers we started to have severe performance issues and to top that some data loss also was happening. It appeared as if data was rolled back. Today, we turned off the error handling and the servers are working like a charm now.

Now, we are not entirely sure if the error handling caused all the problems because we were also trying other things like rebuilding indexes for database tables. Anyone had similar issues? Can cftry cause this kind of data rollbacks?
# Posted By xavier | 4/17/08 4:36 PM
Raymond Camden's Gravatar Not sure about the rollbacks, but i know that using try/catch like that is DEFINITELY not recommended, and I'd be willing to bet is that it is definitely the cause of your performance issues.

You do know that CF5 does support cferror, right? Why not just use that?
# Posted By Raymond Camden | 4/17/08 5:13 PM
gary's Gravatar Ray,

I love to have try/catch blocks on my error page as well, specifically early on.

There is not much worse than throwing an error on your error page while attempting to handle the email; logging for an error.

Dear user, while we were handling a system error another internal error occured, both have been noted
# Posted By gary | 4/23/08 6:50 AM
Carry's Gravatar How does the CFCOMPILE utility interact with CFERROR? (Still on CFMX7 right now.)

Quote from the MX7 LiveDocs: "To ensure that error pages display successfully, avoid using the CFENCODE utility to encode pages that include the CFERROR tag."

OK, I'm concerned about CFCOMPILE with deploy option, not the the old cfencode, and I'm specifying my CFERROR tags in Application.cfc, onRequestStart. Also integrating this with sitewide error management using onError and CFCATCH. So I'm really wondering if a sitewide error management strategy can be impacted by the use of compile. Thank you!

Also, just for clarification: Am I correct in thinking that CFTHROW or CFTHROW will stop execution in it's tracks and there would be no need for a CFABORT in that context? Example without a throw: CFCATCH output something CFABORT /CFCATCH... Of course we would want to use the abort to stop further execution, if that is desired.

Alternative Example: CFCATCH throw or rethrow right here /CFCATCH... In this alternative example, am I correct in thinking that the CFABORT would be unnecessary to halt execution past the CFCATCH, since the CFTRHOW or CFRETHROW would stop execution here and redirect to the error management routines?

Thank you for your post and advice.
# Posted By Carry | 4/27/08 2:12 PM
Mike's Gravatar great examples, great tutorial!
# Posted By Mike | 6/5/08 7:03 PM
Kim Andi's Gravatar Hi:
I'm working on database conversions with several queries using ColdFusion.
I'm outputting the status of each group of queries when they begin and end. I have been hard coding the line numbers and would like to know if there is some CF variable that I can use to output the line numbers dynamically.

The problem is when I add code to the pages, the lines increase or decrease so the line numbers get screwed up.

I tried creating include files, but sometimes that's more work than it's worth.

Any ideas?

Thanks!
# Posted By Kim Andi | 9/2/08 3:56 PM
Raymond Camden's Gravatar This may be a bit silly - but why not just remove the line #s? If you are outputting the result of query GetFoo, a user could simply open the CFM and do a quick ctrl-f to find the query. That seems a heck of a lot easier than worrying about the line numbers.
# Posted By Raymond Camden | 9/5/08 7:17 AM
Kim Andi's Gravatar The reason we're putting in line numbers is being the page has over 8000 lines of codes and queries. The queries look pretty much the same and the only thing that shows when the queries run is this:

I have this at the top of the page:
<cfflush interval="10">
<cfset nowtime = #timeformat(now(),"hh:mm:ss")#>
Then I have the elapsed time calculated in an include file
Then the hard coded line number is output to the screen with the elapsed time so we know how long each query takes to run.

The line numbers are so we can easily find the queries in the file. If the page halts for server time outs or failures, we can quickly get to that location and examine it.

What is "GetFoo"?
# Posted By Kim Andi | 9/5/08 7:40 AM
Raymond Camden's Gravatar Um, not to offend, but if your file has 8K lines of code, it is in serious bad shape. It needs to be rebuilt. There is no hard and fast rule as to how big a file should be - and I've been guilty of large files as well (2k for blog.cfc), but 8k certainly falls into the -way too big- category. Your problem is not the line #s, but the file itsef.

getFoo was simply an example.
# Posted By Raymond Camden | 9/5/08 8:41 AM
xavy's Gravatar My request and exception error types seems to be reversed. Rather, I am getting a request error for all errors (I forced an error using <cfoutput>#nosuchvariable#</cfoutput>). I am using CF 5. I have the two lines:
<cferror type="exception" template="errorException.cfm">
<cferror type="request" template="errorRequest.cfm">
in my application.cfm. On a basic error (like the one above), the page that gets called is the errorRequest.cfm and of course no cfml gets executed. Is there any setting in my server that would cause this?
Thanks!
# Posted By xavy | 9/9/08 7:22 PM
Raymond Camden's Gravatar @xavy - I think I recommended this on this entry somewhere - I may not have - actually I didn't - I recommended it in another blog entry. Anyway, if you find your desired error handler NOT running, it typically means an error in your error handler. Edit errorException.cfm to remove ALL code except "Ray Rocks". If that works, then look at the code you had, and find the problem.
# Posted By Raymond Camden | 9/9/08 8:13 PM
xavy's Gravatar Now, I feel stupid. And Ray really rocks!
Thanks!
# Posted By xavy | 9/9/08 9:36 PM
Michael Lasell's Gravatar Can you access individual errors from a form that has multiple errors? All I get is a list of <li>s with no way to access which is which. ColdFusion doesn't seem to provide a struct with the error and the message as a key pair.
ASP.NET would handle this without a blink.
# Posted By Michael Lasell | 9/16/08 4:12 PM
Raymond Camden's Gravatar Michael, what do you mean by multiple errors? An error, by it's very nature, stops execution. CF gives you full access to the exception. You can have multiple errors on one page if you use try/catch, and in each catch you have access to the full exception as well.

CF handles this w/o a blink too. ;) Unless I'm misreading you somehow.
# Posted By Raymond Camden | 9/16/08 4:20 PM
EstebanD's Gravatar Maybe this was answered before.

When logging or emailing the error I grab the relevant parts of the "error" structure.
On SQL errors I use error.RootCause.sql which reports the offending SQL. The problem is when using cfqueryparam the parameters are shown as (param 1)...(param X). How can I get the values of the parameters?

This is what I found in this regard: http://www.mail-archive.com/cfaussie@googlegroups.... but as you can notice is way too complicated.

Thank you
EstebanD
# Posted By EstebanD | 10/20/08 1:02 PM
Raymond Camden's Gravatar Well it is going to be a bit complicated no matter what. You will need to get the args and replace each ? with the proper arg. I'm not sure that data is available in the error struct. You may have to dump it to see.
# Posted By Raymond Camden | 10/20/08 4:31 PM
Tim Garver's Gravatar I know this is probably already been answered but.....


I have a customer who has an older system, meaning it was coded in CF4
He used a LOT of <INPUT TYPE="HIDDEN" NAME="FIELD_REQUIRED"
VALUE="YOU MUST SELECT A VALUE">
instead of using client side validation.

He came to me a few months ago wanting to upgrade to CF7.
I knew these among many other lazy coding techniques would bit me in the but, and i urged my customer to fix all this prior to the upgrade.

So know he has a site with 1500 documents that have 3000 some odd hidden fields that need to be replaced.

When i setup his App.cfc, i used some generic error catching and just shows an Opps page.
Problem is, those hidden required fields cause a CFTHROW which in turns stops processing and shows the Opps page.

I am now tasked with letting these errors slide through the onError() event. But how?

Is there a certain type of error this produces?
Anyway, thought I would add this to the comments about Error Handling. DONT USE HIDDEN REQUIRED FIELDS. they suck!!

Tim
# Posted By Tim Garver | 11/11/08 4:38 PM
Tim Garver's Gravatar Update on my issue..

turns out this will catch those errors in the onError() event
<cfif Arguments.Exception.message NEQ "Form entries incomplete or invalid.">
<cfoutput>#Arguments.Exception.detail#</cfoutput>
</cfif>

This still does not solve my issue. Seems like you could put a try on the form page to catch the error, wrong. its caught by App.cfc before it hits the form action page.
So ignoring this error seems impossible at this point.

Will update if I find a solution.

Tim
# Posted By Tim Garver | 11/11/08 4:58 PM
Tim Garver's Gravatar sorry,
This should have EQ, not NEQ
<cfif Arguments.Exception.message EQ "Form entries incomplete or invalid.">
<cfoutput>#Arguments.Exception.detail#</cfoutput>
Fill out the form dummy :D
</cfif>
# Posted By Tim Garver | 11/11/08 4:59 PM
Andrew Myers's Gravatar Hi Ray,

Thanks for yet another great article.

I'm using CF7 and whenever I try and log

#arguments.eventname# and #arguments.exception.message#

I get messages like this

"Error","jrpp-738","12/15/08","12:02:33","HRA_V2","Event Name: onRequest"
"Error","jrpp-738","12/15/08","12:02:33","HRA_V2","Message: Event Handler Exception."

I have found I need to look to the "Root Cause" to actually see the information you are mentioning:

      <cflog file="#This.Name#" type="error" text="Template: #arguments.exception.RootCause.TagContext[1].template#">
      <cflog file="#This.Name#" type="error" text="Line: #arguments.exception.RootCause.TagContext[1].line#">
      <cflog file="#This.Name#" type="error" text="Message: #arguments.exception.RootCause.message#">


This produces:

"Error","jrpp-1603","12/19/08","09:18:21","HRA_V2","Template: /www/html/root/throw-error.cfm"
"Error","jrpp-1603","12/19/08","09:18:21","HRA_V2","Line: 1"
"Error","jrpp-1603","12/19/08","09:18:21","HRA_V2","Message: Variable XFHDSHSDHJ is undefined."

Curiously if I put <cfthrow object="#arguments.exception#"> in the onError function I see the real error (eg. Variable XFHDSHSDHJ is undefined), but if I <cfdump> it, it is wrapped in the "Event Handler Exception".

Any ideas? I'm confused as to why this happens to me but not anyone else? ;-)
# Posted By Andrew Myers | 12/18/08 4:28 PM
Raymond Camden's Gravatar Good point on the logging there. I'm not quite sure what your second point is. When you cfdump the error, you are seeing a data-centric view of the exception. Ie, what went wrong. When you let an error flow out naturally, CF will take the exception and display it. You can actually find the exception.cfm file and edit it. It basically does the same thing we do in error handling - inspect the exception and print out the important information.
# Posted By Raymond Camden | 12/18/08 4:35 PM
Andrew Myers's Gravatar Thanks Ray - I think the reason you couldn't understand my second point is that because until now I wasn't aware that the exception.cfm existed and was doing all that for us. :-)

Is there any problem with doing this:

arguments.exception.RootCause.TagContext[1].template

Will the exception passed into the onError() method of Application.cfc always have a RootCause, with a TagContext array of at least 1 element?
# Posted By Andrew Myers | 12/18/08 4:41 PM
Raymond Camden's Gravatar I'm not sure it always will have it - but you can always check:

if structkeyexists(exception, "rootcause") and structkeyexists(exception.rootcause, "tagcontext") and arraylen(exception.rootcaue.tagcontext gte 1
# Posted By Raymond Camden | 12/18/08 4:55 PM
Dave Dugdale's Gravatar What if I don't want to wait for the email to arrive and I am not logged in as admin, can I create a simple way to turn of onError?
# Posted By Dave Dugdale | 1/26/09 11:11 PM
Raymond Camden's Gravatar You could check for the remote IP and say, if it is in a certain safe list, then reveal the error. Really depends on how simple you want it.
# Posted By Raymond Camden | 1/27/09 11:19 AM
Dave Dugdale's Gravatar Great idea! That is an easy one to do - Thanks!
# Posted By Dave Dugdale | 1/27/09 11:42 AM
Dave Dugdale's Gravatar Just thought I would shared my onerror function. When I am at my desktop in my office and the IP matches I get the full error and the email sent to my Iphone gets the small version of the error - while everyone else sees a nicely formatted error:

<cffunction name="onError" returnType="void" output="true">
      <cfargument name="exception" required="true">
      <cfargument name="eventname" type="string" required="true">
      <cfset var errortextemailonly = "">
      <cfset var errortext = "">
      <!--- plain error message email for IPhone --->
      <cfsavecontent variable="errortextemailonly">
         <cfoutput>
         Error on Page:   http://#cgi.server_name##cgi.script_name#/ param: #cgi.query_string#<br>
         <br>
         Refferal Page:   #cgi.http_referer# <br>
         <br>
         User's IP:      #cgi.REMOTE_ADDR#<br>
         <br>
         Server Port:   #cgi.SERVER_PORT#<br>
         <br>
         Error Date:      #dateFormat(now(), "short")# #timeFormat(now(), "short")#<br>
         <br>
         User's Browser:   #cgi.HTTP_USER_AGENT#<br>
         <br>
         ------------------------------------<br>
         CF Error:      #arguments.exception.message#<br>
         </cfoutput>
      </cfsavecontent>
      <!--- full error message for desktop troubleshooting --->
      <cfsavecontent variable="errortext">
         <cfoutput>
         #errortextemailonly#<br>
         <cfdump var="#arguments.exception#" label="Error">
         <cfdump var="#form#" label="Form">
         <cfdump var="#url#" label="URL">
         </cfoutput>
      </cfsavecontent>
      <cfif Application.emailErrorMessaging EQ "on">
         <cfmail
            to="dave@#Application.widgetURL#"
            from="#Application.coname# <dave@#Application.widgetURL#>"
            subject="Error #Application.coname# #arguments.exception.message#"
            type="html"
            server="#Application.mailServer#">
            #errortextemailonly#
         </cfmail>
      </cfif>
      <cfif #REMOTE_ADDR# NEQ #Application.davesIP#>
         <!--- Show visitors the nicely formatted error --->
         <cflocation url="exceptions/error_exception.cfm" addtoken="no">
         <!--- Show me the full error for the desktop --->
         <cfelse>
            <cfoutput>#errortext#</cfoutput>
      </cfif>
   </cffunction>
# Posted By Dave Dugdale | 1/27/09 2:01 PM
Balaji's Gravatar Hi Ray,

We have on missing template handler in CF7 and CF8 and we can call in the Applicaiton.cfc file.But how can we handle the missing template error in CF earlier versions without setting up in ColdFusion administrator.
# Posted By Balaji | 2/23/09 11:50 AM
Raymond Camden's Gravatar I believe the only way to do it is with your 404 handler in the web server. In IIS you have to also use 'check for script existence' in order for it to work. I don't think I ever got it working in Apache though.
# Posted By Raymond Camden | 2/23/09 1:58 PM
Tim Garver's Gravatar the problem with using the webserver is you will loose all your form and request scope vars.

it will work in IIS as Ray points out, also in Apache as well, but you can forgot it if you want to do url rewrite with either of these webservers
# Posted By Tim Garver | 2/23/09 2:54 PM
Raymond Camden's Gravatar Well, form variables shouldn't be posted to a 404, should it? ;)
# Posted By Raymond Camden | 2/23/09 2:56 PM
Tim Garver's Gravatar ideally no, but if you wanted to use that technique to do url rewrites with the older versions of CF, then those are the issues you will face when using a custom 404 file with a web server.

the web server itself with do an internal redirect to the 404 page.

for plain error catching using a custom 404, it will work just fine.
# Posted By Tim Garver | 2/23/09 3:02 PM
Raymond Camden's Gravatar I would not recommend using a 404 for url rewriting. Apache has that built in 'for real' and IIS offers it as well.
# Posted By Raymond Camden | 2/23/09 3:05 PM
Rob Barthle's Gravatar Have a question that my boss wants answered. We have a variety of sites that we run, some using onError() and Application.cfc; and some using CFERROR and Application.cfm. I cannot post code from the sites here (not allowed), but I can tell you this much: in Application.cfm we have CFERROR calls from request, exception, and validation. In Application.cfc, the onError() has handling built in for validation, and all other errors get processed in the same way.

The error handlers work, we get enough usage out of them to know that. There are times though that an error is not caught by our handlers, and gets caught by the site wide error handler.

My boss doesn't believe any error should ever make it that far, and all errors need to get caught and handled by our error handlers regardless of their cause. I believe he is being unrealistic about that, that there are some errors that just cannot be trapped beforehand and that is why the site wide error handler is there. But I need something to back up my thoughts.

I can give you a couple of examples of error messages the site wide has caught, if that is any help.

ERROR DIAGNOSTICS:String index out of range: -1 null <br>The error occurred on line -1. error.message = String index out of range: -1 error.rootCause = java.lang.StringIndexOutOfBoundsException: String index out of range: -1

ERROR DIAGNOSTICS:Session is invalid null <br>The error occurred on line 79. error.message = Session is invalid error.rootCause = java.lang.IllegalStateException: Session is invalid

ERROR DIAGNOSTICS:Operation failed on the data source named ""FREE"". Reason of failure ""java.sql.SQLException: [Macromedia][SQLServer JDBC Driver]Error establishing socket. Connection refused"" <br>The error occurred on line 96. error.message = Operation failed on the data source named ""FREE"". error.rootCause = coldfusion.runtime.ClientScopeDBException: Operation failed on the data source named ""FREE"".
# Posted By Rob Barthle | 2/26/09 9:33 AM
Raymond Camden's Gravatar Well, onError should catch everything, but it can't catch your syntax errors. A site wide error handler CAN catch that. So he will not _always_ be able to use onError.
# Posted By Raymond Camden | 2/27/09 9:50 AM
Mickey's Gravatar First... thanks for a very informative post.

I'm trying to be good and implement a catch-all error handling process using application.cfc. I should also mention that I'm using Fusebox 5.5 and have called the "Super" scope accordingly where needed.

I've tried several variations using this post and other examples but I just can't seem to get detailed info emailed to me while also redirecting the user to a "pretty" page. I'm also writing errors to a log file but so far that doesn't seem to be a problem.

Currently the <cflocation> tag in the onError method of app.cfc is causing it's own forever looping exception. I can instead <cfoutput> the "pretty" message directly from app.cfc but that can leave half drawn pages and other ugly results visible. I also tried GetPageContext() using cfscript but it has the same results as <cflocation>.

I've read about setting up a check to filter "coldfusion.runtime.AbortException" but if I've read correctly that is no longer needed since 7.01 (I'm on 7.02)... either way it has no effect.

My other issue is that the most common errors I'm testing for seem to miss the onError method completely. I can trap them by placing a <cferror type="request" template="Error.cfm"> in the OnRequestStart method, but then I'm limited to how I can format the error page and I can't email the error to myself (as pointed out above). I may just have to accept that but it's worth asking if there might be a better alternative... especially since it seems this may catch more than onError. Would a Try/Catch in OnRequestStart give me more options... or just shoot me in the foot?

Any ideas, clarifications or updates would be very much appreciated.
# Posted By Mickey | 3/26/09 1:23 PM
Raymond Camden's Gravatar You mention that if cflocation, you end up in a loop. Is the page you cflocate to also throwing an error? Like maybe you have a layout custom tag that throws an error. If you cflocate to an html page, I assume that works?
# Posted By Raymond Camden | 3/26/09 9:04 PM
Mickey's Gravatar That's not EXACTLY it (no custom tags) but your suggestion helps a lot. FYI this is not a production site but more of a self-training exercise which I plan to use as a template for new CF sites down the road.

Anyway, I had the cflocation inside the onError method as in your example. To test, I was forcing an exception and seeing the exception error looping in my log file. I now find that the loop has nothing to do with exceptions. It's tied to cflocation.

I took out all of the onError stuff I was trying and then added some <cflog> tags to the methods in application.cfc. Then I just added a cflocation to one of my pages. It still loops but doesn't hit onError. I can see where new requests and sessions are being generated several times per second but never finishing. Fusebox is also reinitialized as part of the loop.

I have two identical files that I've tried to cflocate to. They are very basic and identical except one is named error.cfm and the other is error.htm. You are right that the htm file works just fine though I'm not sure what that tells me. Oh and I can also cflocate to an exernal url like "http://www.google.com"; with no problem.

I suspect I'm just missing something in relation to launching fusebox 5.5 using application.cfc while also trying to do some other creative things with application.cfc. But hey, that's how we learn. If I never broke anything I wouldn't know how to fix anything.
# Posted By Mickey | 3/27/09 11:30 AM
Russ's Gravatar I'm not a big fan of emailing verbose error dumps primarily due to security concerns. Also, verbose error info can take up a lot of room in log files and email storage, especially if you have a busy site that suddenly starts bugging out. Error logs are a pain to wade through as well.

I've developed a solution that stores errors as JSON data in a database. I only store the most recent 100 errors so that if a major glitch happens while I'm asleep it won't clog the database. When an error occurs, I send an email that only contains a basic message with the template and line number, and a link to my "error admin" which displays the verbose error data (that I stored as JSON) using cfdump.

Storing errors in a database lets me flag things that are fixed and things that are not using my "error admin", which is quite handy when I am procrastinating.
# Posted By Russ | 4/23/09 4:25 AM
Russ's Gravatar Oh and of course I convert the JSON data back to a CF object using deserializeJSON before displaying it with cfdump. Just wanted to make that clear.
# Posted By Russ | 4/23/09 4:28 AM
Lee Crockett's Gravatar I just put this code in my site. Thanks for this, it's great. I think finding a bug should have a reward as opposed to the "Sorry we have a problem" page, so I built this. It's entertaining and informative. The true story of the origin of the bug report. Hope you enjoy it.

http://infosavvygroup.com/bugreport_request.cfm
# Posted By Lee Crockett | 4/24/09 10:20 AM
Doug's Gravatar Ok, this is a year-old posting and the comment list is long so forgive me if someone else brought this up...

Anyone notice that when the request error runs (and possibly the other errors too) it puts the error message into the http response header? Is there any way to hide it there so all it shows is a generic 500 error instead of mentioning whatever is going wrong in my code?
# Posted By Doug | 4/27/09 1:11 PM
Raymond Camden's Gravatar I think you want to disable "Enable HTTP status codes" in the ColdFusion administrator.
# Posted By Raymond Camden | 4/27/09 1:18 PM
Doug's Gravatar Ah. But does that mean I'll have to add a cfheader to the error template to send the 500? Or am I misunderstanding how "Enable HTTP Status Codes" works?
# Posted By Doug | 4/27/09 1:26 PM
Raymond Camden's Gravatar Oh I'm sorry - I misread you. You don't want _anything_ about the error to be revealed. Is that what you meant?
# Posted By Raymond Camden | 4/27/09 1:27 PM
Doug's Gravatar Well, yeah, I guess so, I'm just following your suggestion to avoid putting error data even in the error_request.cfm file to keep snooping hackers from finding out what your code is up to. So I'm keeping myself just paranoid enough in case anyone wants to turn my site into a dedicated advertisement for enhancement drugs.

...Speaking of "never too much paranoia", didn't Adobe recently give an update to get ColdFusion to read .htm files like .cfm files? Talk about catering to the paranoid. :D
# Posted By Doug | 4/27/09 1:36 PM
Raymond Camden's Gravatar Hmm. I've got an error handler and it reveals nothing. Not even in the header. Maybe I'm not seeing what you are seeing.

Are you saying you have an error handler, it says something simple "Oops", and yet you can still sniff out the underlying error? (ie, db, bad variable, etc)
# Posted By Raymond Camden | 4/27/09 2:32 PM
Doug's Gravatar Hm. Well, I'm creating a unique situation so maybe it won't occur for exception type errors:

I never got around to defining a mail server on my development server, mostly due to procrastination. So when I created "test.cfm" the error.cfm threw an error because of the cfmail tag which then led to the error_request.cfm. When I then checked the HTTP header on the error_request.cfm I got this: "500 No SMTP server specified for the cfmail tag."

Perhaps it's because it's an error caused by my failure to setup the SMTP server or because it's the error_request template. Maybe?
# Posted By Doug | 4/27/09 3:02 PM
Raymond Camden's Gravatar Ah, your error handler threw an error. Try not to do that. ;) I replicated your setup, but my 500 error did NOT have 'no smtp', instead, it was just:

500 Internal Server Error

Nice and vague.
# Posted By Raymond Camden | 4/27/09 3:10 PM
Doug's Gravatar Oh right, I should have mentioned I was basing all this on the instructions you gave for using the cferror tags instead of the onError method.
# Posted By Doug | 4/27/09 3:20 PM
Raymond Camden's Gravatar Right, I reverted to App.cfm, and even then, I can't see the detailed error info in the response headers.
# Posted By Raymond Camden | 4/27/09 3:22 PM
Jems's Gravatar Hi,
I have spoiled my one day to practice the Coldfusion Validations and I couldnt pass this guy. validateAt is not working for 'onsubmit' or 'blur', working perfectly for 'onserver'.

here is my code
----------------
<html>
<head></head>
<body>
<cfform action="insert2.cfm" method="post">
Enter a Number:
<cfinput type="text" name="ValNumber" maxlength="3" required="yes" validate="integer" validateat="onsubmit">
<cfinput type="submit" name="submit" value="submit">
</cfform>
</body>
</html>

Any help is highly appreciated, thanks

Jems.
# Posted By Jems | 5/15/09 2:41 PM
Rob's Gravatar Do you have javascript enabled? Sounds like maybe not.
# Posted By Rob | 5/15/09 3:48 PM
Don's Gravatar Just to show I'm not a total dunderhead in ColdFusion, let me show you what I've done with errors. This is coming from the onError() in application.cfc.
[Application.cfc]
<cffunction name="onError">
<cfargument name="Exception" required=true/>
<cfargument type="String" name="EventName" required=true/>
<cfif NOT (Arguments.EventName IS "onSessionEnd") OR (Arguments.EventName IS "onApplicationEnd")>
<cfinclude template="includes/dsp_allErrors.cfm">
</cfif>
</cffunction>

[dsp_allErrors.cfm]
<cfsavecontent variable="theError">      #arguments.exception.message#
   #arguments.exception.detail#
   #arguments.exception.tagContext[1].template# LINE #arguments.exception.tagContext[1].line#         <cfif ISDEFINED("arguments.exception.sql")>
   #arguments.exception.sql#
   </cfif>
</cfsavecontent>
<cflog file="AppErrorLog" type="error" text="#theError#">

I just pull the info out that I need instead of doing a full dump. How many acutally use the stack dumps etc? I haven't used a stack dump since my machine language days (which is back when we had to slide beads around on a framework)
Of course the user only sees "YOU BROKE IT YOU MORON!" message and I get the email telling me to check the log.
# Posted By Don | 5/26/09 1:22 PM