| Print Article Return |
CF Error Handling - A pinch of this, a pinch of that
By: Al DiMarzio, HB GraphicsGuilford, CT I received a call from a client the other day informing me that his on-the-floor Internet-based Customer Kiosk had generated another CF error message. This has been ongoing for about six months with perhaps one or two error messages a week. The code of course, had been examined rigorously, but perhaps it was time for some generalized CF error handling. An additional suspect was the wireless communications link. (The first lesson a software developer learns is to blame the hardware). Yet a third suspect was XHML processing to/from a third-party web site. (The problem was later discovered to be the wireless link that would drop the connection). The problem solving approach had to accomplish two things: send useful debugging information to the developer, and provide a graceful recovery for the user. Looking at the code I selected two options: use the <cftry><cfcatch> tags or use the <cferror> tag. After a few experiments I selected the <cferror> tag combined with some HTML form coding and a little javascript code ... a pinch of this, and a pinch of that.
<cftry><cfcatch> tags approach On the first pass I headed for the most versatile approach: the <cftry><cfcatch> tags. Using these, I can surround my application code with the <cftry> tags (what is "trying" to happen), and place the what-to-do-if-there-is-an-error code between the <cfcatch> tags (where we "catch" the error). Sounded easy to me so I took the following generalized approach:
[application code here] <cfcatch type="any"> [ask user to try again] [send email to myself about problem] </cfcatch> </cftry> Errrr, the <cfinclude> approach did not work. Upon checking with Macromedia's CF Forum I found that <cftry> and <cfcatch>, and perhaps other CF tags, need to be on the same page as the application code to work correctly. I had too many pages to fiddle with so I scratched this approach. The <cferror> tag approach The next approach was to use the <cferror type="Request" template="error_kicker.cfm"> tag until I read that you cannot use CF tags inside the referenced template file. That is, the "error_kicker.cfm" page would have to be completely non-CF code. Since I wanted to retain the site-standard system of header, footer, menu <cfinclude>s this would mean duplicating code and the error section becoming non-modular. At about this time a light bulb illuminated above my balding head, albeit dimly … use a combination of HTML form and javascript coding on the page referenced by the <cferror> tag. The referenced page would then send the parameters to a second page which would process the email and provide recovery for a user. There are many ways to solve this kind of a problem, however here is the approach I implemented.
In the Application.cfm page I inserted the <cferror> tag code which looks like: <cferror type="Request" template="error_kicker.cfm"> When an error occurs, the following information is available to the page referenced by the "template", I.e. the "error_kicker.cfm" page.
The referenced template page While the <cferror> tag has a lot going for it, the little extra coding and a second page provide a very professional look to the system. But most of all, the second page allows for a user friendly recovery where I can use all my header, menu and footer includes, maintaining the modular system design. Putting the error information into an HTML form looks like the following:
<head> <title></title> </head> <body> <!--- Use an HTML form to preserve and pass error information ---> <form Name="kicker" action="error_handler.cfm" method="post"> <input type="hidden" name="Browser" value="#error.Browser#"> <input type="hidden" name="Diagnostics" value="#error.Diagnostics#"> <input type="hidden" name="HTTPReferer" value="#error.HTTPReferer#"> <input type="hidden" name="QueryString" value="#error.QueryString#"> <input type="hidden" name="DateTime" value="#error.DateTime#"> <input type="hidden" name="RemoteAddress" value="#error.RemoteAddress#"> <input type="hidden" name="Template" value="#error.Template#"> </form>
<!-- document.kicker.submit() // --> </script> </body> </html> Nothing magical here. This page simply receives the HTML form information and attempts a graceful recovery. The code looks something like the following: Starting with the usual web page which conforms to the rest of the site.
<head> <title>WXYZ Company</title> <link rel=stylesheet type="text/css" href="scripts/wxyz.css"> </head> <body> <div align="center"> <img src="images/header_ooops.jpg" width="600" height="73" alt="" border="0> <cfinclude template="insert_topmenu.cfm">
<table width="550" border="0" cellpadding="0" cellspacing="0"> <tr>
We are sorry to report <b>there has been a system error</b> and any information<br> you have entered into the forms has been lost.<br> <br> We regret your inconvenience and would <b>appreciate it if you would try again</b>.<br> <br> Should you get this message a second time, please contact a store manager.<br> <br> <b>Thank you</b> and have a fine day at WXYZ's.<br> <br> </td></tr> </div>
<cfmail to="someone@developer.com" from="error@wxyz.com" Subject="Error message from Kiosk"> Browser: #form.Browser# Date/Time: #form.DateTime# Diagnostics: <html><body> #form.Diagnostics# </body></html> Referer: #form.HTTPReferer# Query String: #form.QueryString# Remote Address: #form.RemoteAddress# Template; #form.Template# </cfmail> </body> </html> Seven years ago when many of us were programming mostly in HTML, code and web design was simple. But technology waits for no one. So in today's applications we use multiple languages, Java applets and various aides to create a variety of web sites and solve problems. Like Chefs seasoning food, developers have their "spices" to judiciously sprinkle on applications ... a pinch of this, and a pinch of that makes a robust application. About the Author For additional information about the author, please select Author Biography. |
| Print Article Return |