Over the last week or so, I've made some pretty large changes to the code behind my ColdFusion blogging software. As part of those changes, I've started using my Application.cfc's onSessionEnd() event handler. This event handler is used to tear down a given session, providing access to both the ending session as well as the sister application scope. The onSessionEnd() event handler accepts the session and application scopes as the first and second arguments respectively. Unfortunately, as I was making my updates, I accidentally switched the order of these two arguments. This error went unnoticed for two days because it turns out that neither onSessionEnd() nor onApplicationEnd() errors show up in the ColdFusion error logs.
Just to give you a taste of this error in action, here is a tiny Application.cfc ColdFusion framework component that I used to narrow down the problem:
<cfcomponent output="false" hint="I define the application settings and event handlers."> <!--- Define application settings. ---> <cfset this.name = hash( getCurrentTemplatePath() ) /> <cfset this.applicationTimeout = createTimeSpan( 0, 0, 0, 15 ) /> <cfset this.sessionManagement = true /> <cfset this.sessionTimeout = createTimeSpan( 0, 0, 0, 5 ) /> <cffunction name="onSessionEnd" access="public" returntype="void" output="false" hint="I tear down the session."> <!--- Define arguments. ---> <cfargument name="sessionScope" type="any" required="true" hint="I am the session scope being torn down." /> <cfargument name="applicationScope" type="any" required="true" hint="I am the application scope." /> <!--- Log the session length. ---> <cfdump var="#arguments.sessionScope.dateInitialized# : #now()#" output="#expandPath( './log.htm' )#" format="html" /> <!--- Return out. ---> <cfreturn /> </cffunction> <cffunction name="onApplicationEnd" access="public" returntype="void" output="false" hint="I tear down the application."> <!--- Define arguments. ---> <cfargument name="applicationScope" type="any" required="true" hint="I am the application scope." /> <!--- Log the application length. ---> <cfdump var="#arguments.applicationScope.dateInitialized# : #now()#" output="#expandPath( './log.htm' )#" format="html" /> <!--- Return out. ---> <cfreturn /> </cffunction> </cfcomponent>
As you can see, both the onSessionEnd() and onApplicationEnd() ColdFusion application event handlers make reference to a dateInitialized property that doesn't exist. If I run this application and wait for both the application and the session to time out, neither undefined variable reference error will show up in the ColdFusion application log file. I've tested this both locally on ColdFusion 8 and ColdFusion 9 as well as in production on ColdFusion 8 and this remains true across the board.
If I add an onError() event handler to my Application.cfc ColdFusion framework component, both of these errors will be caught internally (at which point I can respond to them however I need to); but, without out any explicit error handling within the application, it appears that onApplicationEnd() and onSessionEnd() errors will go unnoticed.
As I was writing this, I did a bit of Googling to see if anyone else had come across this problem. As it turns out, Mark Kruger discussed the onSessionEnd() aspect in a blog post 5 years ago. That's a long time ago. This problem feels like a bug; but, perhaps if it has been around for so long, it is the expected behavior of the asynchronous event handlers (seeing as they sort of happen outside of the application)?
NOTE: My blogging software does have an onError() event handler. I was actually not getting alerts for a different bug altogether - one in my code. But, the debugging of that bug lead me to this separate problem.
Want to use code from this post? Check out the license.