Application.cfc OnRequest() Method Affects OnError() Arguments

Posted July 23, 2007 at 9:22 AM

Tags: ColdFusion

The other week, Thomas Messier pointed out to me that my ColdFusion Application.cfc Tutorial was a bit incomplete in the fact that it did not address the changes in the OnError() event method arguments that depend on the existence of the OnRequest() event method. To be totally honest, I did not know anything about this. I pretty much always use the OnRequest() event method, so I have never had to deal with errors that occur outside of it.

I set up a quick, little test application to see what was actually going on. In the Application.cfc ColdFusion component below, my OnRequestStart() checks for a Delete flag in the URL. If it exists, it simply deletes the OnRequest() method. Then, I throw an error in my index.cfm page and compare the two different sets of arguments.

My ColdFusion Application.cfc:

 Launch code in new window » Download code as text file »

  • <cfcomponent
  • output="false"
  • hint="Handles application level evnts.">
  •  
  • <!--- Set up application. --->
  • <cfset THIS.Name = "ErrorTest" />
  • <cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 0, 0, 5 ) />
  • <cfset THIS.SessionManagement = false />
  •  
  • <!--- Set up page request. --->
  • <cfsetting
  • showdebugoutput="false"
  • />
  •  
  •  
  • <cffunction
  • name="OnRequestStart"
  • access="public"
  • returntype="boolean"
  • output="false"
  • hint="Pre-page processing for each page request.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="TargetPage"
  • type="string"
  • required="true"
  • hint="The template being requested."
  • />
  •  
  • <!---
  • Check to see if we want to keep the OnRequest()
  • method or delete it from the app component.
  • --->
  • <cfif StructKeyExists( URL, "delete" )>
  •  
  • <!--- Delete the OnRequest() method. --->
  • <cfset StructDelete( THIS, "OnRequest" ) />
  •  
  • </cfif>
  •  
  • <!--- Return out. --->
  • <cfreturn true />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnRequest"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="Processes the requested template.">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="TargetPage"
  • type="string"
  • required="true"
  • hint="The template being requested."
  • />
  •  
  • <!--- Include the requested template. --->
  • <cfinclude template="#ARGUMENTS.TargetPage#" />
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  •  
  • <cffunction
  • name="OnError"
  • access="public"
  • returntype="void"
  • output="true"
  • hint="Fires when an exception occures that is not caught by a try/catch block">
  •  
  • <!--- Define arguments. --->
  • <cfargument
  • name="Exception"
  • type="any"
  • required="true"
  • />
  •  
  • <cfargument
  • name="EventName"
  • type="string"
  • required="false"
  • default=""
  • />
  •  
  •  
  • <!---
  • Dump out the ARGUMENTS scope. Here, we want to see
  • how the argument change depending on whether or not
  • we have the OnRequest() method.
  • --->
  • <cfif StructKeyExists( THIS, "OnRequest" )>
  •  
  • <!--- Use label with onrequest. --->
  • <cfdump
  • var="#ARGUMENTS#"
  • label="OnError() - WITH OnRequest()"
  • />
  •  
  • <cfelse>
  •  
  • <!--- Use label withOUT onrequest. --->
  • <cfdump
  • var="#ARGUMENTS#"
  • label="OnError() - WITHOUT OnRequest()"
  • />
  •  
  • </cfif>
  •  
  • <!--- Return out. --->
  • <cfreturn />
  • </cffunction>
  •  
  • </cfcomponent>

And then, my simple index.cfm:

 Launch code in new window » Download code as text file »

  • <!--- Force an error. --->
  • <cfset x = y />

Here, I am simply referring to a variable, Y, that does not exist.

When I run the page without any query string flag, the Application.cfc runs with the OnRequest() method and produces this OnError() arguments CFDump (I have collapsed some of the items for better display):


 
 
 

 
ColdFusion Application.cfc OnError() Arguments With OnRequest() Presence  
 
 
 

Now, let's compare that to what happens when I call the same page, but this time, I send the "?delete" flag that will cause the OnRequestStart() method to delete the OnRequest() method from the Application.cfc. This time, my CFDump output is much smaller:


 
 
 

 
ColdFusion Application.cfc OnError() Arguments Without OnRequest() Presence  
 
 
 

The difference here, as Thomas Messier pointed out, is that the error generated without the OnRequest() method's presence does NOT have the RootCause structure. I don't know why this is, but this is certainly good to know.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Other Searches  |  Print Page





Reader Comments

Mar 23, 2009 at 6:45 PM // reply »
3 Comments

not sure what the difference is, but i will have to investigate a little. The application.cfc i am using does not have an OnRequest() and the ARGUMENTS.EXCEPTION.RootCause struct _is_ there, however if i extend that cfc and put my own OnError handler in the cfc that is extending the main one the ARGUMENTS.EXCEPTION.RootCause struct _is not_ available.

Very odd, this is definitely something that needs to be cleared up!


Mar 23, 2009 at 6:47 PM // reply »
7,560 Comments

@Joey,

That is a funky difference!


Mar 1, 2010 at 3:54 PM // reply »
4 Comments

I am using the OnError function in application.cfc and I noticed a strange occurance. If I mistype a cf tag (ie. <cfssset x = y />) the OnError does not catch it, just a generic CF error is displayed. Furthermore even if I use a cftry cfcatch around that code, with type = "any", CF still displays its own error and will not allow me to catch it.

Not that I plan on purposely adding bad code, but it would be nice if I could catch it just in case. Do you have any idea if this is a known bug?


Mar 1, 2010 at 4:06 PM // reply »
4 Comments

I forgot to mention that my mistyped tag was located in my index.cfm file.

Interestingly enough I created the same error in a cfc which I called as an object. In that way the error was caught and displayed the way I wanted to from the OnError function.

Am I missing something?


Mar 1, 2010 at 4:27 PM // reply »
7,560 Comments

@Jason,

It's possible that parsing errors are not handled in the same way; theoretically, a site would never go live *with* parsing errors.

It's also possible you have an error in your onError() method handler; if you do, the original error will be allowed to bubble up to the top (without the error in the onError() event handler being displayed).


Mar 1, 2010 at 4:42 PM // reply »
4 Comments

@Ben

Thank you for responding so quickly.

I thought I would post my code. I was just doing a simple POC when I noticed this.

application.cfc:
----------------------------------------
<cffunction name="OnRequest" access="public" returntype="void" output="true">

<cfargument name="TargetPage" type="string" required="true" />

<cfinclude template="#Arguments.TargetPage#" />

<cfreturn />
</cffunction>

<cffunction name="OnError" access="public" returntype="void" output="true">

<cfargument name="pass_cfcatch" required="Yes" type="any" />

<cfdump var="#pass_cfcatch#" />
</cffunction>
----------------------------------------

The file that the OnError would not catch was onerror_parsing.cfm with just <cfssset x = y /> in it.

The other file that OnError DID catch was onerror_parsing_cfc.cfm that called a cfc with <cfset Variables.onerror_template = createObject("component", "onerror_parsing").init() />. In the onerror_parsing.cfc file I had the same <cfssset x = y /> in it.

I only noticed this cause I was trying to see how the OnError would react to different types of errors. I agree with you and hope that any error like this would never reach the live server (especially since I have a Dev AND Staging server), I just thought it was worth noting.

Thanks again.


Mar 1, 2010 at 4:55 PM // reply »
4 Comments

Okay, sorry about flooding your comments, but on a whim I tried one more thing. I made no changes to the application.cfc file I posted above, but this time I created another .cfm file that simply had <cfinclude template="onerror_parsing.cfm" /> in it.

When loading it this way the OnError in the application.cfc caught and dumped the error.

Of course, I think the moral of this story is don't let these kind of errors make it to your live server, but again, I thought it was worth noting.

On a side note, I did work for a company that had a programmer (who was eventually denied access to the live server) who kept insisting on making changes directly on the live server - he would occasionally make these kind of errors. Not fun.


Mar 1, 2010 at 6:10 PM // reply »
7,560 Comments

@Jason,

Hmm, odd that it would catch one parsing error and not the other. There's probably something subtle and tricky going on :)


Post Comment  |  Ask Ben

Recent Blog Comments
Mar 19, 2010 at 9:29 AM
Be Careful When Including Images In jQuery Auto-Suggest
@Jim, I've only ever messed with the config in FireFox. Not sure what's available in the other browsers. ... read »
Mar 19, 2010 at 9:27 AM
ColdFusion 8 ImageDrawTextArea() (Inspired By Barney Boisvert!)
@Martin, It's been a while since I looked at this; but, I don't think I handled explicit line breaks because it just made the calculations harder. Perhaps in another version. ... read »
Mar 19, 2010 at 9:23 AM
Ask Ben: Parsing CSV Strings With Javascript Exec() Regular Expression Command
@Jens, Ahh, gotcha. Yeah, the textarea is probably gonna be safe cross-browser. ... read »
Mar 19, 2010 at 9:22 AM
How ColdFusion CreateObject() Really Works With Java Objects
@Dmitry, Word up - createObject() can do a whole bunch of things. It's probably one of the best updates to the language. ... read »
Mar 19, 2010 at 9:19 AM
Learning ColdFusion 9: Resetting Applications With ApplicationStop()
@Rocky, Yeah, I assume it will flush all application-scope variables when you can applicationStop(), regardless of where they are initialized. As far as the connectivity between application and s ... read »
Mar 19, 2010 at 9:15 AM
Ask Ben: Getting The Start And End Dates Of The Previous Week In ColdFusion
@David, It gets the last week. I goes back 7 days, and then finds the start / end of that week. ... read »
Mar 19, 2010 at 9:12 AM
Using Inline List Elements
@ben: thank you very much - that helped me a lot ;) ... read »
Mar 19, 2010 at 9:10 AM
Ask Ben: Selecting XML Attributes Given Other XML Attributes
@Tom, That's odd. Looks like a malformed XML problem. Make sure you aren't missing any of the ">" closing brackets or something. ... read »