last updated:

There’s an excellent tutorial on writing an #objectNotFoundHandler written by Samuel Reynolds, but it only covers the mainResponder website framework, upon which Manila was built. The problem is that Manila has its own #objectNotFoundHandler, and it adds functionality to Manila (rather than just generating the error that someone would see if they went to a page that didn’t exist).

What functionality does it add? Manila has the ability for the admin to configure an XML-based hierarchy for his or her site, so that messages and stories can be lumped into tree-like structures despite being messages in the (flat-file organized) discussion group. So, on this site, http://q.queso.com/photos/ is a link to the master page of everything configured in the XML hierarchy as within the “photos” category, and http://q.queso.com/photos/newyears is actually just a link to message number 72 rendered in a story template.

Of course, there’s no object in my Manila website guest database that is named “photos”, so when you request http://q.queso.com/photos/, there’s nothing in the database location there, and the webserver fires off the #objectNotFoundHandler. In Manila, that handler then checks the XML hierarchy to see if there’s a category named “photos”, and if there is, it sends you to the right page; only if there’s nothing in the hierarchy that matches your request do you get an error page.

So, if you want to write your own #objectNotFoundHandler, you need to take into account that the default Manila one has functionality that you don’t want to lose. The way that I’ve discovered to do this is to wrap the default Manila one in a try statement; that way, if there’s truly an error, you catch the scriptError that’s thrown by the hierarchy-checking script, and can call your own custom error page or script in the else clause.

My #objectNotFoundHandler script looks like this:

local {
	pta = html.getPageTableAddress()};
try {
	return (manilaSuite.hierarchyPage ())}
else {
	if tryError beginsWith "!" { // custom error or redirect message
		scriptError(tryError)}
	else {
		return(pta^.tools^.pageNotFound())}}

Two notes:

  • I’ve got a script in my Manila website #tools table named pageNotFound that generates my custom error page; that’s what I’m calling with the pta^.tools^.pageNotFound() line.
  • The script that’s called by Manila’s default #objectNotFoundHandler, manilaSuite.hierarchyPage(), throws scriptError conditions for some things that aren’t necessarily indications that the requested page doesn’t exist. (For example, if you were to request http://q.queso.com/photos, without the trailing slash, it would throw a scriptError that would redirect your browser to http://q.queso.com/photos/, with the trailing slash.) That’s why I need to test the tryError to see what it contains; if it has a leading exclamation point (!), then it’s a condition that’s intended to be handled by mainResponder (like a redirect), so I continue to pass it along with the scriptError call. Otherwise, I call my custom error page.
Comments

Great report, Jason. I learned mucho.

• Posted by: David Theige on Feb 13, 2000, 10:27 AM

Aha! Brilliant explanation. Going to play now…

Thanks!

• Posted by: Andrew Duncan on Feb 13, 2000, 10:09 PM

Glad that I could help (Andrew & David)… I definitely was getting ill of seeing the default error page, since it seemed easy to at least send my users to the search engine instead.

/j

• Posted by: Jason Levine on Feb 13, 2000, 10:19 PM

Today, I realized something — the page that’s generated when an object isn’t found should return the HTTP server status code 404, since it is a legitimate not-found error.

So… when I say that I have a script in my #tools table named pageNotFound, one thing that that script should do is set the HTTP status code to 404:

local {
	pta = html.getPageTableAddress() };
pta^.code = 404
• Posted by: Jason Levine on Feb 23, 2000, 2:46 PM
Please note that comments automatically close after 60 days; the comment spammers love to use the older, rarely-viewed pages to work their magic. If comments are closed and you want to let me know something, feel free to use the contact page!