Strange ColdFusion Application.cfc Error Update - It Works AND It Breaks
So, I have an update to my very strange Application.cfc errors. I took the advice of some people and I tried moving the code into new files in new directories to see if it was a template caching issue. Now, I only have an Application.cfc, and index.cfm, and trace.txt files. The methods in the Application.cfc ONLY do a CFFile / Append to the trace.txt file so I can see if and when system events fire. The index.cfm ONLY dumps out the APPLICATION scope. There is no other code being run here, no other error handling.
Here is the updated Application.cfc
<cfcomponent
displayname="Application"
output="true"
hint="Handle the application.">
<cfscript>
THIS.Name = "App Event Testing 2";
THIS.ApplicationTimeout = CreateTimeSpan( 0, 0, 0, 15 );
THIS.SessionManagement = true;
THIS.SessionTimeout = CreateTimeSpan( 0, 0, 0, 10 );
THIS.LoginStorage = "SESSION";
THIS.SetClientCookies = true;
</cfscript>
<cfsetting
requesttimeout="10"
showdebugoutput="false"
enablecfoutputonly="false"
/>
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="true"
hint="Fires when the application is first created.">
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnApplicationStart"
addnewline="true"
/>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction name="OnSessionStart" access="public" returntype="void" output="true"
hint="Fires when the session is first created.">
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnSessionStart"
addnewline="true"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="true"
hint="Fires when prior to page processing.">
<!--- Define arguments. --->
<cfargument name="TargetPage" type="string" required="yes" />
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnRequestStart"
addnewline="true"
/>
<!--- Return out. --->
<cfreturn true />
</cffunction>
<cffunction name="OnRequest" access="public" returntype="void" output="true"
hint="Fires after pre page processing is complete.">
<!--- Define arguments. --->
<cfargument name="TargetPage" type="string" required="yes" />
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnRequest"
addnewline="true"
/>
<!--- Include the requested page. --->
<cfinclude template="#ARGUMENTS.TargetPage#" />
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="OnRequestEnd" access="public" returntype="void" output="true"
hint="Fires after the page processing is complete.">
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnRequestEnd"
addnewline="true"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="OnSessionEnd" access="public" returntype="void" output="true"
hint="Fires when the session is terminated.">
<!--- Define arguments. --->
<cfargument name="SessionScope" type="struct" required="true" />
<cfargument name="ApplicationScope" type="struct" required="false" default="#StructNew()#" />
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnSessionEnd : [ID - #ARGUMENTS.SessionScope.CFID#] [TOKEN - #ARGUMENTS.SessionScope.CFTOKEN#]"
addnewline="true"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
<cffunction name="OnApplicationEnd" access="public" returntype="void" output="false"
hint="Fires when the application is terminated.">
<cfargument name="ApplicationScope" type="struct" required="false" default="#StructNew()#" />
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnApplicationEnd : [NAME - #ARGUMENTS.ApplicationScope.ApplicationName#]"
addnewline="true"
/>
<!--- 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.">
<!--- Define arguments. --->
<cfargument name="Exception" type="any" required="true" />
<cfargument name="EventName" type="string" required="false" default="" />
<cffile
action="APPEND"
file="#ExpandPath( './trace.txt' )#"
output="OnError : [#ARGUMENTS.Exception.Message# - #ARGUMENTS.Exception.Type#] #ARGUMENTS.Exception.Detail#"
addnewline="true"
/>
<!--- Return out. --->
<cfreturn />
</cffunction>
</cfcomponent>
Here is the output that it produces:
OnApplicationStart
OnSessionStart
OnRequestStart
OnRequest
OnRequestEnd
OnSessionEnd : [ID - 43666] [TOKEN - 32723233]
OnError : [Event Handler Exception. - Expression] An exception occurred when invoking a event handler method from Application.cfc The method name is: onSessionEnd.
OnApplicationEnd : [NAME - App Event Testing 2]
OnError : [Event Handler Exception. - Expression] An exception occurred when invoking a event handler method from Application.cfc The method name is: onApplicationEnd.
As you can see, the OnSessionEnd and OnApplicationEnd methods are both firing and both can successfully reference their passed in scope arguments. However, both of them seem to fire an OnError even of type "Expression". I am not going to be too concerned with this, I suppose, as all the events ARE firing. I just wish I knew why error was firing as well.
Thanks for all your help and if any one sees what's going on, please let me know. Thanks!
Want to use code from this post? Check out the license.
Reader Comments
@Ben:
I'm going to take a guess and say it's because your CFRETURN tags are returning neither true or false. Try leaving the CFRETURN tags or setting their values to an actual boolean value.
@Ben:
I just ran that code under CFMX 7,0,2,142559 and here's what my log looks like after several runs:
OnApplicationStart
OnSessionStart
OnRequestStart
OnRequest
OnRequestEnd
OnSessionEnd : [ID - 2100] [TOKEN - 11429582]
OnSessionStart
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnSessionEnd : [ID - 2100] [TOKEN - 11429582]
OnApplicationEnd : [NAME - App Event Testing 2]
OnApplicationStart
OnSessionStart
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
OnRequestStart
OnRequest
OnRequestEnd
(I just rapidly hit refresh on my browser.)
Dan,
I tried taking out the CFReturn statements at one point and it didn't seem to matter. The test you just ran, did you leave those in?
Maybe it's just my machine then :(
@Ben:
I ran the code as-is. A couple of notes:
1) Try copying and pasting the code from this blog--to make sure there aren't any funky characters in your template (I've seen templates behave strangely when saved in one charset that actually contained invalid chars.)
2) Check the version of your server. Perhaps you're missing a patch (or I am) and it's something w/the version of CFMX you're running. I'm using teh DevNet edition.
Just so you don't think it is just you, I was getting the exact same error several months ago with similar code. Never found a solution.
Here is the code I used:
<cffunction name="onApplicationEnd" returnType="void" output="false">
<cfargument name="applicationScope" required="true">
</cffunction>
<cffunction name="onSessionEnd" returnType="void" output="false">
<cfargument name="sessionScope" type="struct" required="true">
<cfargument name="appScope" type="struct" required="false">
</cffunction>
It didn't happen on my dev machine, it was only on the live site.
I still had one of the error dump emails:
TagContext array [empty]
Type java.lang.NullPointerException
Type: Expression Template: C:\dev\ozarka\Application.cfc? Tag Context:
array [empty]
Exception:
struct
Detail An exception occurred when invoking a event handler method from Application.cfc The method name is: onSessionEnd.
Scott, thank you for making me feel that perhaps I wasn't a raving lunatic :)
Dan,
Yeah, copy and paste still the same issue. I am running Enterprise version 7,0,1,116466. Looks like we are missing the 7,0,2 patch. Hmmm, that might be it.
I started getting this error after doing a structclear on the session and application scope. I removed the function, onRequestStart and am now getting the error in a different template all together.
Did you ever figure out a direct cause for this error?
I am now having this issue as well. CF7. Happens in my subdir app.cfc which has SUPER.OnRequestStart(ARGUMENTS.Page) and this is the line that gets the error
<cflocation addtoken="no" url="/signin.cfm?err=notloggedin" />
even tho like you said, everything still works. I know this is an old thread but hopefully someone found the answer since then?
Derek
@Derek,
Unfortunately, I have no new insight to add to this.
If it helps at all, I discovered this blog post while searching for the same issue, but in my case it was in the OnRequestEnd method that was giving me problems. I eventually tracked down the error, and I thought I would share this with everyone in the hopes that it helps you figure out what's going on.
In my case, the OnRequestStart method was doing a number of things, but the two important pieces to this discussion were:
1. Forcing the page to come through as secure by redirecting to the https port if it wasn't.
2. Setting a flag variable that the OnRequestEnd method checks.
Every time the page came in on the wrong port (and app.cfc had to redirect them) I was getting that "Event handler exception" error. But whenever I would dump out the variables to see what could be erroring, everything looked good and was working. And on top of it, I wasn't actually seeing the error, it would only show up in the logs.
I'm sure you've guessed by now, but the problem was that #2 above wasn't actually happening on the initial request if I redirected the user (because of #1), so the OnRequestEnd method didn't have the flag variable defined which it was expecting. Apparently, the OnRequestEnd method still runs anyway even if you cflocate. That makes total sense, but I still wasn't expecting it. And I wasn't seeing the error, because it was showing up on the initial request, not the second one (after the redirect) which worked fine.
So anyway, that's how I solved my problem.
@Chris,
Hmm, I was under the impression that onRequestEnd() did not execute after a CFLocation tag. I am not sure if I have ever actually tested that, though. What version of ColdFusion are you using?
@Ben,
I'm running 9.0.1, and it was definitely firing the OnRequestEnd method.
@Chris,
Now you have my curiosity thoroughly piqued. I'll have to look into this in the morning.
@Chris,
Thanks for the heads up on this - it appears that the onRequestEnd() event handler behavior has changed in ColdFusion 9:
www.bennadel.com/blog/2050-Changes-In-CFLocation-OnRequestEnd-Behavior-In-ColdFusion-9-s-Application-cfc.htm
Good find!
I found that an EventHandlerException which was being thrown in my CF9 code was actually pointing to a problem in my bean creation. I have two different application.cfc files. One for a scheduled task and the other a main application. The main application was using coldspring to maintain the beans. The task app was not. The init functions of the service beans were no longer instantiating correctly from the main application. Simply handling the two different init possibilites corrected the error. Event Handler Exception is not exactly what I would expect from this type of problem, but it is what was being thrown.