Forum OpenACS Q&A: broken ns_returnnotfound and templated error return pages

I found a bug in the request processor which prevented ns_returnnotfound (and other internalredirect style commands) from working properly.

I also realized that with 4.x we lost the error files from the tree and the param file. Its something I think we should put back and make sure work. Templated error files that preserve the persistent navigation etc. are important from a usability standpoint (and it is not at all obvious to new users of the toolkit how to set things up properly). If anyone has already done error pages for this maybe you could pass them on.

The files from 3.4 (basically one line place holders) were:

    ns_param   NotFoundResponse /global/file-not-found.html
    ns_param   ServerBusyResponse /global/busy.html
    ns_param   ServerInternalErrorResponse /global/error.html
    ns_param   ForbiddenResponse /global/forbidden.html
    ns_param   UnauthorizedResponse /global/unauthorized.html
I think they belong at acs-subsite/www/global and probably should be subsite aware templated files.

Again, if anyone has already done this or has any other suggestions, please pass them on.

I don't think anyone has done anything with these and, yes, you're right on all counts as far as I'm concerned.

Something I did sneak in awhile back is another acs-templating/acs-integration proc called "ad_return_exception_template".  It's useful for returning templated error pages, originally in my case those returned by on_error blocks attached to db_transaction calls.  My idea was to start chasing down common error pages and replace them with templated versions.

Returning the standard pages you're talking about is easier because no parameters are involved (in the db error case the error message needs to be passed as a template param, in the general case arbitrary params and ad_return_exception_template supports that plus an error return code).

You might talk to Bruno Mattarollo about 404s.  He implemented a templated 404 page for Greenpeace that fits into our scheme that allows arbitrary Greenpeace National suborganizations to use their own custom version.

He ran into some issues/bugs, in fact possibly the same one you're talking about or something specific to our stuff, I'm not sure (GP Planet runs a customized version of parts of the request processor).  His email address is Bruno Mattarollo <mailto:bruno.mattarollo@ams.greenpeace.org> and he'll be more than glad to share what he's learned, if you want to ask.

Are 404s from requests for *.tcl pages handled differently from 404s for *.html and *.adp pages in OACS 4.5? They are in 3.2.5:
  • a 404'd .html or .adp request will get the file (say, /global/file-not-found.html) specified by ns_param NotFoundResponse
  • a 404'd .tcl request, however, does not; in /tcl/ad-aolserver-3.tcl.preload, there's an ns_register_proc that sends all requests to ns_sourceproc which tries to source the file and calls ns_returnnotfound directly if it fails. In the AOLServer api (http://www.aolserver.com/docs/devel/tcl/api/conn.html#ns_return), there doesn't appear to be any way to intervene in ns_returnnotfound to tart up what the user sees beyond the stark "Not Found" message.
The problem for a heavily .tcl site is that if you're not sending out .html or .adp files, your templated page doesn't go out like you want.

Did you hack ns_sourceproc (or replace it entirely in the new request processor schema) in order to create uniform system behavior in these two cases? Or is there some benefit to having AOLServer deliver two different kinds of 404s?

Slightly off-topic:  When I had the aforementioned parameters set with those defaults, AOLServer could not find the /global directory.  What happened next was horrible.  When a URL was not found (ie 404), the servername-error.log file reported that the "recursion limit" of 3 was reached and the server would hang and not process new connections.  From reading the aolserver mailing list archives, the server gives up after the third attempt to locate the custom 404 file.  According to the severname-error.log file, scheduled procs were still running.  After I commented out the parameters and restarted the server, the "recursion limit" error disappeared along with the server stalls.  I'm fairly certain that the two are related since the server was stalling all of Saturday when the parameters were set and users tried to reach non-existent files, and it humming along today with no problems.  I'll know for sure tomorrow when the load goes up again.

Would this behavior be caused by some bug in AOLServer or in OpenACS?

Stan - I don't have an acs 3.x version installed but with the 4.x stuff the 404 is still being sent out by ns_returnnotfound (which internally calls Ns_ConnRedirect to restart handling at the rp_handler). It isn't clear to me why 3.x 404 return would not just work). The only difference between what 4.x does and ns_sourceproc does is that ns_sourceproc calls ns_returnnotfound with a $conn arg.

The fix I made was entirely a 4.x change and no I did not have to touch ns_sourceproc (although the request processer only calls ns_sourceproc if it knows the file exists and does it's own ns_returnnotfound if it does not).

Gilbert - I think it's more likely the bug you saw would be an AOLServer bug since once you get the recursion limit error very little oacs code gets run. It is concievable it is trace filter problem and you might try putting debug statements in any you have running. Also, I did probably 50 404 gets without seeing the server hang and I get lots of hits from code red etal and those do not seem to hang the server either.

Jeff, 3.x 404's do in fact work "correctly" for both *.tcl files and *.html/adp files -- just differently. The neato page you can specify with ns_param NotFoundResponse displays in the latter but not the former case.

In /tcl/ad-html.tcl, ad_serve_html_pages is ns_register_proc'd to run for all *.html/adp pages. If it can't find the requested url, it returns

ns_returnfile 404 text/html $full_path
Whereas in /tcl/ad-aolserver-3.tcl, ns_sourceproc is ns_register_proc'd to run for all *.tcl pages. If it can't find the requested url, it returns
ns_returnnotfound $conn

As you point out, the difference is that the latter returns the conn arg to the user's connection. I don't understand the underlying plumbing of http to know whether this is important. Looks to me as if it would be a trivial thing to modify ns_sourceproc to send back an ns_returnfile 404 instead.

Can anyone think of a reason not to do this and unify file-not-found behavior across all page types in a site?

Stan, sorry, I forgot there is a second set of params you also need to set...
ns_section ns/server/${server}/redirects
    ns_param   404                global/file-not-found.html
    ns_param   403                global/forbidden.html