Handling unknown events in Model-Glue

What happens in a Model-Glue application when you pass in an unknown event? An error is thrown. While this makes sense - it may not be desired behavior for an application. For example - I'd probably consider most unknown events to be 404 errors. So how can you handle it?

Model-Glue lets you define the event to fire when an error occurs. In Model-Glue: Unity you can find this setting in the ColdSpring.xml file

<property name="defaultExceptionHandler"><value>exception</value></property>

The "out of the box" exception event in Model-Glue prints out a few pieces of information from the exception. Obviously you wouldn't have that on a live site. Normally I simply take the exception and mail it to myself (along with the form, url, and session scopes).

So how did I handle the unknown event? The first thing I did was dump the exception that Model-Glue was throwing. I was hoping a certain code would be thrown, but the only information I could use was the exception message. It was in this form:

Model-Glue: There is no known event handler for "x".

So I first added this to my exception file:

<!---
Look for event handler missing.
--->
<cfif findNoCase("Model-Glue: There is no known event handler for", exception.message)>
   <cflocation url="/">
</cfif>

When this didn't work - I did a quick view source and discovered there were two spaces between Model-Glue: and the message. So I quickly changed it to:

<!---
Look for event handler missing.
--->
<cfif findNoCase("Model-Glue: There is no known event handler for", exception.message)>
   <cflocation url="/">
</cfif>

Obviously you should consider doing more than just sending the user away. You could log the event to the database and see if there is a particular event being called multiple times.

You could also use logic to check for typos or commonly mistyped URLs. For example - someone keeps trying to load the event, "page.rss/", at RIAForge. Notice the / at the end? I whipped up this code to handle it:

<cfif findNoCase("Model-Glue: There is no known event handler for", exception.message)>
   <cfset unknownEvent = rereplace(exception.message, ".*""(.*?)"".*", "\1")>
   <cfif unknownEvent is "page.rss/">
      <cflocation url="#viewState.getValue("myself")#page.rss" addToken="false">
   <cfelse>
      <cflocation url="/">
   </cfif>
</cfif>

By the way - I bugged Joe to consider adding a "Unknown Event" configuration setting to the framework.

Comments

Joe Rinehart's Gravatar Hey Ray - Nice post!

I'll also be typing framework exceptions before releasing MG:U. Sorry about that.
# Posted By Joe Rinehart | 11/5/06 9:44 PM
O?uz Demirkap?'s Gravatar Nice to have one. :) Thanks Ray.
# Posted By O?uz Demirkap? | 11/5/06 10:35 PM
Ken Dunnington's Gravatar Is there a way to get the known event handlers? Your idea of catching mistyped URL's is really interesting. It'd be cool to catch something like index.cfm?event=Users.list and redirect it to index.cfm?event=User.list programmatically (maybe using a soundex or some fancy regex?) instead of hard-coding it in. Add SES URL's on top of that and then you're really cooking! (Or asking for trouble, depending on who you ask :))
# Posted By Ken Dunnington | 11/6/06 9:32 AM
Raymond Camden's Gravatar I don't think so. Joe, a "isValidEvent()" function could be useful perhaps, as well as "getValidEvents()".
# Posted By Raymond Camden | 11/6/06 9:51 AM