A few days ago I posted a simple article discussing how you could handle session timeouts in an Ajax application (Example of handling session time outs in an Ajax application). If you haven't yet read that entry, please do so. The basic gist of the article was to make use of a custom exception that your Ajax application could pick up on. This worked - but only because I had tested on my development server where Robust Exception Info was turned on. Reader Jason pointed out that in production, where this is turned off (everyone does have it turned off, right?) the code didn't work.
Turns out my method of looking for a string within the exception doesn't work when the exception info is suppressed in production. Of course, this is totally obvious now, like most things after a bug is found. I apologize for the mistake and I hope this entry makes it a bit more simpler. As I mentioned in the last entry, there are multiple ways to solve this problem. Here is how I modified my application.
My technique was to simply add a header to the response. Unfortunately, you can't use the cfheader tag within a script based CFC. I had to make a file just to include it:
public void function onError(exception,eventname) {
if(arguments.exception.rootcause.message == "SessionTimeout") {
include "header.cfm";
throw(message=arguments.exception.rootcause.message);
}
writelog(file='application', text='my onerror ran: #serializejson(arguments.exception.rootcause.message)#');
}
As you can see, I'm still throwing the exception, but I'm also including a file named header.cfm. That just has:
<cfheader name="SessionTimeout" value="1">
Finally - I modified my ajaxSetup error handler then to check for this header. I've never checked headers in JavaScript before but it's pretty simple:
var sessionTimeout = x.getResponseHeader("SessionTimeout");
if(sessionTimeout == 1) {
alert("Your session has timed out.");
location.href = 'login.cfm';
}
Pretty simple, right? Off the top of my header, another way to handle this would be to redirect to a special CFM page that just outputs SessionTimeout. Your error handler should still run since JSON wasn't returned. You could then check for that string. I haven't tried that method but it's another alternative to consider.
Does this make sense? I'm still thinking of an entry that handles this and shows handling errors in general.