Site-Wide Error Handler Config Files
Ray Camden recently gave another friendly reminder to use a site-wide error handler for your ColdFusion site if you're not using <cferror> or onError in your Application.cfc. I've been doing a lot of fine-tuning on my intranet apps at work lately, and realized I never implemented any across-the-board error protection like this.
So, using TechNote 19198 as a starting point, I began writing my error handler.
Being that all my apps go into Subversion now, I am obsessive about putting specific settings of an app into config files, so that my light OCD doesn't flare up when those settings need to change (heaven forbid I bump a revision number just for a configuration change!).
This presents a light challenge for a couple reasons. First, the error handler is executed within the application scope of the application that threw the error. It does not automatically run the application.cfm or application.cfc in its own directory. Second, the working path is also the path of the template that threw the error.
These facts threw a wrench in standard operation for me. I store my config file settings in the application scope; that wasn't going to work for the error handler. And I'd like my config file to be in the same directory as my error handler, so I need to be able to FIND the config file.
Finding the config file is easy. Although ExpandPath() will operate from the working path of the erring template, GetCurrentTemplatePath() will still return the error handler's path. Use the GetDirectoryFromPath() function and append the filename of your config file.
Great, now we have a path to look at.
I use a custom tag (hey, it was written before CFMX) named <cf_AppConfig> that receives a config file path, retrieves the application settings from the file, and stores them in the Application scope. In my case, I needed to modify this custom tag to allow me to specify the scope the settings would be written in. Then, I simply write the settings in the Variables scope instead of the Application scope, to avoid accidentally overwriting any values of the existing application (or throwing an error if the Application scope isn't available!).
I can now cleanly retrieve settings from a config file for my error handler.
What kind of settings am I placing in this error handler's config file? Well, the error handler accomplishes three tasks: (a) Display a friendly error page, instead of the ugly ColdFusion default error handling. (b) Log the error with <cflog>. (c) Send details of the error via email.
That said, I put the email sender, recipient, and subject line in the config file. I also could put the name of the log file that <cflog> should write to.
I also have a config setting for the "Mode" of the server. In my case, I have a <cf_SiteConfig> custom tag that retrieves various site-wide settings from a global config file stored outside the web root. The "Mode" is one of those settings; it is set to "Production" for our live server and "Development" for my local PC and my QA server.
By looking at the "Mode" of your server, you can have your site-wide error handler "disable" itself on your development boxes. After all, I don't want to be getting email notifications all day long from my development server as I'm debugging my apps, and I don't want to hide the error information. To do that is simple. Manually throwing an error in your error handler will cause ColdFusion to abort the error handler and resort back to its default error management.
You could accomplish something similar by just looking to see if you're on localhost, or 127.0.0.1.
That way, if the browser is on the same machine as the server (i.e. while you are developing locally), the error handler would abort. The CGI.REMOTE_ADDR approach would work for you while developing and browsing on a local machine, but would not work for a QA server. For that, store the "Mode" in a config file.
