Customizing the Look of Error Messages


The Web application framework provides a simple way to customize the look of error messages that can occur while users are accessing your pages. As you know, error messages might appear because of syntax problems in your code, because of database connection problems, or just because user have left out one or more required fields while filling out a form.

The application framework lets you customize any of these error messages. You can even hide them from the user's view entirely if you want. This enables you to maintain a consistent look and feel throughout your application, even when those dreaded error messages occur. You even have multiple ways to handle exceptions. We will cover both, dealing with the simplest solution first.

Introducing the <cferror> Tag

You use the <cferror> tag to specify how error messages should be displayed. Customizing the error messages that appear throughout your application is generally a two-step process:

1.

First, you create an error display template, which displays the error message along with whatever graphics or other formatting you consider appropriate.

2.

Next, you include a <cferror> tag that tells ColdFusion to display errors using the error display template you just created. In general, you place the <cferror> tag in your Application.cfc file.

Table 19.5 shows the attributes supported by the <cferror> tag.

Table 19.5. <cferror> Tag Attributes

ATTRIBUTE

DESCRIPTION

type

The type of error you want to catch and display using your customized error display template. The allowable values are Request, Validation, and Exception. The first two types are covered in this chapter; the last two are discussed in Chapter 32, "Error Handling." If you don't supply this attribute, it is assumed to be Request, but it's best to always supply it.

template

Required. The relative path and filename of your customized error display template. You specify the filename in the same way as you would specify an include file with the <cfinclude> tag.

mailto

Optional. An email address for a site administrator that the user could use to send some type of notification that the error occurred. The only purpose of this attribute is to pass an appropriate email address to your error display template. It doesn't actually send any email messages on its own.

exception

Optional. The specific exception that you want to catch and display using your customized error display template. The default value is Any, which is appropriate for most circumstances. See Chapter 32 for a discussion of the other values you can supply here.


The next two sections discuss how to customize the error messages displayed for exception errors (syntax errors, database errors, and so on) and validation errors (when the user fails to fill out a form correctly).

Request vs. Exception Error Templates

If you want to customize the way error messages are displayed, you first must create an error display template. This template is displayed to the user whenever a page request can't be completed because of some type of uncaught error condition.

ColdFusion actually allows you to create two types of error display templates:

  • Request Error Display Templates. The simplest way to show a customized error message. You can include whatever images or formatting you want so that the error matches your site's look and feel. However, CFML tags, such as <cfoutput>, <cfset>, or <cfinclude>, are not allowed. CFML functions and variables also are not allowed.

  • Exception Error Display Templates. These are more flexible. You can use whatever CFML tags you want. For instance, you might want to have ColdFusion automatically send an email to the Webmaster when certain types of errors occur. The main caveat is that ColdFusion can't display such a template for certain serious errors.

  • Validation Error Display Templates. This template is used when a form using hidden form-field or onSubmit validation is submitted. Like the Request Error template, you can't include any ColdFusion tags or functions. ColdFusion will pass along the specific problems the form had.

In general, the best practice is to create one template of each type. Then the exception template is displayed most often, unless the error is so serious that ColdFusion can't safely continue interpreting CFML tags, in which case the request template is displayed. The request template also kicks in if the exception template itself causes an error or can't be found.

NOTE

If you don't care about being able to use CFML tags in these error display templates, you can just create the request template and skip creating the exception one.


NOTE

For those history buffs out there, the request type of error display template is a holdover from earlier versions of ColdFusion. At one time, you could never respond intelligently to any type of error. Thankfully, those days are over.


Creating a Customized Request Error Page

To create the request display template, do the following:

1.

Create a new ColdFusion template called ErrorRequest.cfm, located in the same directory as your Application.cfc file. Include whatever images or formatting you want, using whatever <img> or other tags you would normally. Remember to not put any CFML tags in this template.

2.

Include the special ERROR.diagnostics variable wherever you want the actual error message to appear, if you want it to appear at all. Contrary to what you are used to, the variable should not be between <cfoutput> tags.

3.

If you want, you can include the special ERROR.mailTo variable to display the email address of your site's Webmaster or some other appropriate person. You also can use any of the other variables shown in Table 19.6.

Table 19.6. Special ERROR Variables Available in an Error Display Template

ATTRIBUTE

DESCRIPTION

ERROR.browser

The browser that was used when the error occurred as reported by the browser itself. This is the same value that is normally available to you as the #CGI.http_user_agent# variable, which generally includes the browser version number and operating system.

ERROR.dateTime

The date and time the error occurred, in the form MM/DD/YY HH:MM:SS. You can use the dateFormat() function to format the date differently in an exception template, but not in a request template.

ERROR.diagnostics

The actual error message. In general, this is the most important thing to include (or not to include) in an error display template. Please note that the exact text of this message can be affected by the settings currently enabled in the Debugging Settings page of the ColdFusion Administrator. See Chapter 17, "Debugging and Troubleshooting," for details.

ERROR.generatedContent

The actual HTML that had been generated by the requested ColdFusion template (and any included templates, and so on) up until the moment that the error occurred. You could use this to display the part of the page that had been successfully generated.

ERROR.HTTPReferer

The page the user was coming from when the error occurred, assuming that the user got to the problem page via a link or form submission. This value is reported by the browser and can sometimes be blank (especially if the user visited the page directly by typing its URL). Note the incorrect spelling of the word referrer.

ERROR.mailTo

An email address, presumably for a site administrator or Webmaster, as provided to the <cferror> tag. See the following examples to see how this actually should be used.

ERROR.queryString

The query string provided to the template in which the error occurred. In other words, everything after the ? sign in the page's URL. This is the same value that is normally available to you as the #CGI.query_string# variable.

ERROR.remoteAddress

The IP address of the user's machine.

ERROR.template

Filename of the ColdFusion template (.cfm file) in which the error occurred.


4.

Include a <cferror> tag in your Application.cfc file, with the type attribute set to Request and the template attribute set to ErrorRequest.cfm. This is what associates your error display template with your application.

Listing 19.9 is a good example of a request error display template. Note that no <cfoutput> or other CFML tags are present. Also note that the only variables used are the special ERROR variables mentioned previously.

Listing 19.9. ErrorRequest.cfmCustomizing the Display of Error Messages
 <!---  Filename: ErrorRequest.cfm  Created by: Nate Weiss (NMW)  Please Note Included via <CFERROR> in Application.cfc ---> <html> <head><title>Error</title></head> <body> <!--- Display sarcastic message to poor user ---> <h2>Who Knew?</h2> <p>We are very sorry, but a technical problem prevents us from showing you what you are looking for. Unfortunately, these things happen from time to time, even though we have only the most top-notch people on our technical staff. Perhaps all of our programmers need a raise, or more vacation time. As always, there is also the very real possibility that SPACE ALIENS (or our rivals at Miramax Studios) have sabotaged our website.<br> <p>That said, we will naturally try to correct this problem as soon as we possibly can. Please try again shortly. <!--- Provide "mailto" link so user can send email ---> <p>If you want, you can <a href="mailto:#ERROR.mailTo#">send the webmaster an email</a>. <p>Thank you.<br> <!--- Maybe the company logo will make them feel better ---> <img src="/books/2/448/1/html/2/../images/logo_b.gif" width="73" height="73" alt="" border="0"> <!--- Display the actual error message ---> <blockquote>  <hr><font size="-1" color="gray">#ERROR.diagnostics#</font> </blockquote> </body> </html> 

NOTE

ColdFusion also provides the <cftry> and <cfcatch> tags, which enable you to trap specific errors and respond to or recover from them as appropriate. See Chapter 32, "Error Handling," for details.


Listing 19.10 shows how to use the <cferror> tag in your Application.cfc file. Note that the email address webmaster@orangewhipstudios.com is being provided as the tag's mailTo attribute, which means that the Webmaster's email address will be inserted in place of the ERROR.mailTo reference in Listing 19.9. Figure 19.4 shows how an error message would now be shown if you were to make a coding error in one of your templates.

Figure 19.4. Customized error pages help maintain your application's look and feel.


To test this listing, save it as Application.cfc, not Application4.cfm.

Listing 19.10. Application4.cfmUse of the <cferror> Tag in Application.cfc
 <!---  Filename: Application.cfc (The "Application Component")  Created by: Raymond Camden (ray@camdenfamilyc.om)  Purpose: Sets "constant" variables and includes consistent header ---> <cfcomponent output="false">   <cfset THIS.name = "ows23">   <cferror type="Request" template="ErrorRequest.cfm"            mailto="webmaster@orangewhipstudios.com">   <cffunction name="onApplicationStart" returnType="boolean" output="false">     <!--- When did the application start? --->     <cfset APPLICATION.appStarted = now()>     <cfreturn true>   </cffunction>   <cffunction name="onApplicationEnd" returnType="void" output="false">     <cfargument name="appScope" required="true">     <!--- Log how many minutes the application stayed alive --->     <cflog file="#THIS.name#" text= "App ended after #dateDiff('n',ARGUMENTS.appScope.appStarted,now())# minutes.">   </cffunction>   <cffunction name="onRequestStart" returnType="boolean" output="true">     <!--- Any variables set here can be used by all our pages --->     <cfset request.dataSource = "ows">     <cfset request.companyName = "Orange Whip Studios">     <!--- Display our Site Header at top of every page --->     <cfinclude template="SiteHeader.cfm">     <cfreturn true>   </cffunction>   <cffunction name="onRequestEnd" returnType="void" output="true">    <!--- Display our Site Footer at bottom of every page --->    <cfinclude template="SiteFooter.cfm">   </cffunction> </cfcomponent> 

Additional ERROR Variables

In Listing 19.9, you saw how the ERROR.diagnostics variable can be used to show the user which specific error actually occurred. A number of additional variables can be used in the same way. You will see several of these used in Listing 19.11 in the next section.

NOTE

Note that the ERROR.generatedContent variable is not available in request error display templates.


TIP

These are the only variables you can use in request error display templates. You can use all types of ColdFusion variables in exception error display templates, discussed next.


Creating a Customized Exception Error Page

You have seen how to create a request error display template, in which you are prevented from using any CFML tags or functions. Now you can create an exception error template, in which you can use whatever CFML tags and functions you want.

For instance, Listing 19.11 is similar to Listing 19.10, but it doesn't display the ERROR.diagnostics message to the user. This means that the user won't know which type of error actually occurred. After all, your users might not care about the specifics, and you might not want them to see the actual error message in the first place. In addition, instead of allowing the user to send an email message to the Webmaster, this template has ColdFusion send an email message to the Webmaster automatically, via the <cfmail> tag.

Now all you have to do is add a second <cferror> tag to your Application.cfc file, this time specifying type="Exception" and template="ErrorException.cfm". You should put this <cferror> tag right after the first one, so the first one can execute if some problem occurs with your exception error display template. Since this modification is so simple, it won't be listed in the chapter. It is included in the CD with the name Application5.cfc.

Listing 19.11. ErrorException.cfmSending an Email When an Error Occurs
 <!---  Filename: ErrorException.cfm  Created by: Nate Weiss (NMW)  Please Note Included via <CFERROR> in Application.cfc ---> <html> <head><title>Error</title></head> <body> <!--- Display sarcastic message to poor user ---> <h2>Who Knew?</h2> <P>We are very sorry, but a technical problem prevents us from showing you what you are looking for. Unfortunately, these things happen from time to time, even though we have only the most top-notch people on our technical staff. Perhaps all of our programmers need a raise, or more vacation time. As always, there is also the very real possibility that SPACE ALIENS (or our rivals at Miramax Studios) have sabotaged our website.<br> <p>That said, we will naturally try to correct this problem as soon as we possibly can. Please try again shortly. Thank you.<br> <!--- Maybe the company logo will make them feel better ---> <img src="/books/2/448/1/html/2/../images/logo_b.gif" width="73" height="73" alt="" border="0"> <!--- Send an email message to site administrator ---> <!--- (or whatever address provided to <cferror>) ---> <cfif ERROR.mailTo neq "">  <cfmail to="#ERROR.mailTo#" from="errorsender@orangewhipstudios.com"  subject="Error on Page #ERROR.Template#">  Error Date/Time: #ERROR.dateTime#  User's Browser: #ERROR.browser#  URL Parameters: #ERROR.queryString#  Previous Page: #ERROR.HTTPReferer#  ------------------------------------  #ERROR.diagnostics#  </cfmail> </cfif> 

NOTE

Because sending automated error emails is a great way to show how exception templates can be used, the <cfmail> tag has been introduced a bit ahead of time here. Its use in Listing 19.11 should be self-explanatory: The ColdFusion server sends a simple email message to the Webmaster. The email will contain the error message, date, browser version, and so on because of the ERROR variables referred to between the opening and closing <cfmail> tags.


See Chapter 27, "Interacting with Email," for details.


TIP

The Webmaster could also look in ColdFusion's logs to see any errors that might be occurring throughout the application.


See Chapter 17, "Debugging and Troubleshooting," for details.


Creating a Customized Validation Error Page

Now, your application responds in a friendly and consistent manner, even when problems occur in your code. The Web application framework also allows you to customize the page that appears if a user's form input doesn't comply with the validation rules you have set up using the hidden form fields technique (as described in Chapter 13, "Form Data Validation").

To create your own validation error display template, follow the same steps you performed to create your request template (see the section "Creating a Customized Request Error Page," earlier in this chapter). The only differences are that you use the special ERROR variables listed in Table 19.7 instead of those in Table 19.6, and that you should specify type="Validation" in the <cferror> tag you include in your Application.cfc file.

Table 19.7. Special ERROR Variables Available in an Validation Display Template

ATTRIBUTE

DESCRIPTION

ERROR.invalidFields

The actual problems with the way the user has filled out the form. The text is preformatted as a bulleted list (the text includes <ul> and <li> tags). In general, you would always want to include this in your error display template; otherwise, users wouldn't have any indication of what they did wrong.

ERROR.validationHeader

The default text that normally appears above the bulleted list of problems when you are not using a customized error message. The message reads, "Form Entries Incomplete or Invalid. One or more problems exist with the data you have entered." You can include this variable in your template if you want this wording to appear. Otherwise, you can provide your own text.

ERROR.validationFooter

The default text that normally appears above the bulleted list of problems when you are not using a customized error message. The message reads, "Use the Back button on your Web browser to return to the previous page and correct the listed problems."


Listing 19.12 shows a completed validation error display template. Figure 19.5 shows how it would look to end users, if they were to submit a form without filling it out correctly.

Figure 19.5. A customized display template makes it less jarring for users who fail to fill out a form correctly.


As before, since the modification to the Application.cfc file was so simple, it is not listed here but included in the CD as Application6.cfc.

Listing 19.12. ErrorValidation.cfmCustomizing the Display of Form Validation Messages
 <!---  Filename: ErrorValidation.cfm  Created by: Nate Weiss (NMW)  Please Note Included via <CFERROR> in Application.cfc ---> <html> <head><title>Form Fields Missing or Incomplete</title></head> <body> <!--- Introductory Message ---> <img src="/books/2/448/1/html/2/../images/logo_b.gif" width="73" height="73" alt="" align="absmiddle"      border="0"> <font size="4">Please take a moment...</font><br clear="all"> Maybe it's because we are in the entertainment business and thus have lost touch with the kinds of problems that ordinary people have, but we can't quite figure out how to deal with the information you just provided. Here are the "problems" that we need you to correct: <!--- Display actual form-field problems ---> #ERROR.invalidFields# <!--- Link back to previous page ---> <p>Please <a href="javascript:history.back()">return to the form</a> and correct these minor problems.<br> Or, just use your browser's Back button.<br> </body> </html> 

Using the OnError Method

As we discussed earlier in the chapter, the Application.cfc contains a set of special methods that are executed depending on certain situations. We demonstrated how the onApplicationStart and onApplicationEnd methods are executed automatically based on the life of the ColdFusion application. One more special method is the onError method. As you can probably guess, this method is called whenever an exception occurs. Unlike the <cferror> tag, which is tied to a specific error type or exception, the onError method will fire on any error.

So how can you use this method? The method could do many of the things demonstrated in the listings we've already covered. You can mail the error to the administrator, or log the error to a file or database. You can even display a message to the user, but remember that the onError method will be run for any error. So for example, if your onApplicationEnd method throws an error, the onError method will run. The output won't be displayed, obviously, since no one is there to actually see it.

Another option to consider when using the onError method is to use it to handle the non-visual portions of the error (emailing the administrator, logging, etc.), and use the <cfthrow> tag to let your <cferror> tags take over. The <cfthrow> tag is discussed in Chapter 32. Think of the onError method as simply taking care of the error temporarily, and then passing it back to ColdFusion. If you have already created your request, exception, and validation templates, this approach lets you continue using those templates, while adding a bit of extra functionality to your application. Listing 19.13 demonstrates the latest version of our Application.cfc file, this time with an onError method. If you save this template, be sure to save it as Application.cfc, not Application7.cfc.

Listing 19.13. Application7.cfcWorking with onError
 <!---  Filename: Application.cfc (The "Application Component")  Created by: Raymond Camden (ray@camdenfamilyc.om)  Purpose: Sets "constant" variables and includes consistent header ---> <cfcomponent output="false">   <cfset THIS.name = "ows23">   <cferror type="Request" template="ErrorRequest.cfm"            mailto="webmaster@orangewhipstudios.com">   <cferror type="Exception" template="ErrorException.cfm"            mailto="webmaster@orangewhipstudios.com">   <cferror type="Validation" template="ErrorValidation.cfm"            mailto="webmaster@orangewhipstudios.com">   <cffunction name="onApplicationStart" returnType="boolean" output="false">     <!--- When did the application start? --->     <cfset APPLICATION.appStarted = now()>     <cfreturn true>   </cffunction>   <cffunction name="onApplicationEnd" returnType="void" output="false">     <cfargument name="appScope" required="true">     <!--- Log how many minutes the application stayed alive --->     <cflog file="#THIS.name#" text= "App ended after #dateDiff('n',ARGUMENTS.appScope.appStarted,now())# minutes.">   </cffunction>   <cffunction name="onRequestStart" returnType="boolean" output="true">     <!--- Any variables set here can be used by all our pages --->     <cfset request.dataSource = "ows">     <cfset request.companyName = "Orange Whip Studios">     <!--- Display our Site Header at top of every page --->     <cfinclude template="SiteHeader.cfm">     <cfreturn true>   </cffunction>   <cffunction name="onRequestEnd" returnType="void" output="true">               <!--- Display our Site Footer at bottom of every page --->               <cfinclude template="SiteFooter.cfm">   </cffunction>   <cffunction name="onError" returnType="void" output="false">     <cfargument name="exception" required="true">     <cfargument name="eventName" type="string" required="true">     <!--- Use the cflog tag to record info on the error --->     <cfif arguments.eventName is "">       <cflog file="#THIS.name#" type="error"              text="#arguments.exception.message#">     <cfelse>       <cflog file="#THIS.name#" type="error"  text="Error in Method [#arguments.eventName#] #arguments.exception.message#">      </cfif>      <!--- Let the <cferror> tags do their job. --->      <cfthrow object="#arguments.exception#">   </cffunction> </cfcomponent> 

The only thing new in this template is the onError method at the end, so we'll focus on that portion. The onError method is automatically passed two arguments. The first is the exception itself. This is just like the ERROR struct discussed earlier. It has the same values and we can use it to email, log to a file, or anything else. The second argument passed to the method is the name of the event that was running when the exception occurred. This argument will only have a value when the error occurs within the Application.cfc file itself. So for example, if the onApplicationStart method threw an error, that method name would be passed to the onError method. The onError method in listing 19.14 checks to see if an eventName argument has a value. If it doesn't, it simply logs the error. Note that it uses the same file value as the onApplicationEnd's <cflog> tag. The value passed to the log is just the exception message. If the eventName argument wasn't blank, the text passed to the log is modified slightly to contain the event name as well. Lastly, we use the <cfthrow> tag to pass the error back out again from the onError method. Don't worry too much about this tag now; it's covered later in Chapter 32. Just consider the onError method here as being part of a "chain" of code blocks that will handle the error.

NOTE

ColdFusion also provides the <cftry> and <cfcatch> tags, which allow you to trap specific errors and respond to or recover from them as appropriate. See Chapter 32, "Error Handling," for details.




Macromedia Coldfusion MX 7 Web Application Construction Kit
Macromedia Coldfusion MX 7 Web Application Construction Kit
ISBN: 321223675
EAN: N/A
Year: 2006
Pages: 282

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net