How to Handle Cold Fusion Errors – onError() Function and More
After lots of research surrounding the onMissingTemplate() function, cflog, and creating a custom error log, it became very event that the information you have would be great, I say great except; a server issue….
Source: Colorblind Programming
<cfsetting showdebugoutput=”no” requesttimeout=”200″ />
<!— quick and dirty way of getting the file separator —>
<cfset logsFile = Server.ColdFusion.RootDir & “#s#logs#s#yourFile.log”>
<cfif not fileExists(logsFile)>
Error: log file #logsFile# does not exist
Showing contents of #logsFile#
myfile = FileRead(logsFile);
Okay, now that you have looked at this nice bit of code – the example would be a working solution except for one slight factor, not being able to read the log files on a shared server. Just to verify it. I contacted the hosting company directly to find out whether they allowed this option or not and was told “NO”. Of which in turn – also meant; after finding that out, the cflog tag at this point is considered useless because you can not read the log files on a shared server, main reason it can not be created and secondly it can not be read and then in turn cfoutput.
This was unfortunate since I was using the cflog tag in my Application.cfc file and it does not allow to read or create a .log file on the shared server. So the solution was to just write the errors to different error log files under the root directory named “logs”. O’ in case you were wondering, you can not use directory path hierarchy for cflog file on the server either.
Depending on the type of error system being created, it seemed logical just to create a system that captured the errors from the Application.cfc file as much as possible. I managed to use some custom error system structure by utilizing the cftry and cfcatch tags on certain areas.
Secondly, anything that was not caught by this custom error system was then caught by the onError() function from the Application.cfc. Also if my memory serves me well, the cferror tag can only be used for catching errors in an Application.cfm and not Application.cfc. Believe I read that in some CF10 documentation.
Next, was to output the errors to the corresponding page such as 400, 401, 403, 404, 500 etc… These are the custom pages created and not system defaults, which are crap anyway. In order to show the errors being caught by the Application.cfc, I made use of the onError() function and wrote the exception errors to a .rtf file and then output the exception errors onto the page of choice by reading the file and outputting the text onto the error page.
| Event: #arguments.eventName#
| Detail: #arguments.exception.detail#
| Message: #arguments.exception.message#
| Stack Trace: #arguments.exception.stackTrace#
| Type: #arguments.exception.type#
| Name: #arguments.exception.name#
| Template: #arguments.exception.tagContext.template#
| Line: #arguments.exception.tagContext.line#
| Raw Trace: #arguments.exception.tagContext.raw_trace#
Of course you can pick which one’s you want to write and output from the rich text file, but you get the picture. After a little trial and error (“HA, HA”)… I ended up being able to output the errors the way I wanted and some crappy system default error page. So as you can see, I now have logged my errors and then outputted those errors onto the custom error pages.
The onMissingTemplate() function was a tad different. The difference here was finding a way to show the 404 page when the file did not end in .cfm. Let me tell you, not knowing that the onMissingTemplate() function does not work on any other types of files; but .cfm files was the first step in making this function work correctly. Could not figure out for a little while why it just did not do what I wanted it to do.
Reason being, thought it would be easy to just do redirects with the onMissingTemplate() for non-existent pages or for redirecting old pages to the new pages. Well, that did not go so well at first. After realizing the onMissingTemplate() function only works with files ending in .cfm, I decided to just do a mod rewrite with a .htaccess file. Problem solved for 301 redirects.
Now, I did some further research and came across some code written by Ben Nadel and got a few tips from Ray Camden that helped out along the way with this onMissingTemplate() function. The code I still am playing around with but have found some usage for it all ready was created by Ben Nadel.
<cfset requestedURI = listrest(cgi.query_string, “;”) />
<!— strip port —>
<cfset requestedURI = Replace(requestedURI, “:80”, “”, “ALL”) />
<!— if just asking for folder’s default doc, append index.cfm —>
listlast(requestedURI) does not contain “index.cfm” and listfind(“gif,jpg,png,pdf,xml,css,.js,htm,tml”, right(requestedURI, 3)) eq 0>
requestedURI contains “/?”>
<cfset requestedURI = replace(requestedURI, “?”, “index.cfm?”) />
<cfelseif requestedURI contains “?”>
<cfset requestedURI = replace(requestedURI, “?”, “/index.cfm?”) />
<cfelseif Right(requestedURI, 1) neq “/”>
<cfset requestedURI = requestedURI & “/index.cfm” />
<cfset requestedURI = requestedURI & “index.cfm” />
<!— <cflocation url=”#variables.requestedURI#” addtoken=”false” statuscode=”301″ />–>
<!— <cfheader statuscode=”404″ statustext=”Object Not Found”> —>
<p>This document can not be found.</p>
I commented out the bottom portion because I did not want the page to go to the home page each time a file object was not found. Plus, the 404 code caused me to be in a continuous redirect loop since I had already used it above this code. As for the output I did not need that as well since the output I wanted was being written to my logs/.rtf file with the exception errors or whatever error message I chose.
After implementing this snippet, “Thanks Ben” – I was able to output to my 404 page my errors even when a file did not end in .cfm. As you can tell, you can take this error system as far as you like, but in the end; do whatever works best for you.
This was the only solution I could create for getting around the issue concerning a shared hosting environment.
“On to the next task”.