You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by David Taylor <Da...@cox.net> on 2005/03/15 06:18:54 UTC

Taming missing page errors

While Tapestry is a great framework, it has a few rough edges. One of 
these is how it handles common problems such as missing pages. Throwing 
an ApplicationRuntimeException is a bit unfriendly for a common error 
and leaves users with a sense that the application is seriously broken. 
While this is definitely more informative than a blank page (I hate it 
when that happens), it is preferable to interpret common error 
conditions and display a more user-friendly message.

After think about this issue for a while, I decided to find a way to 
make Tapestry handle missing pages better. Poking around in the tapestry 
code I discovered this could be accomplished with a custom 
SpecificationResolverDelegate. When Tapestry is unable to find a page, 
it calls the findPageSpecification method of the resolver delegate. By 
simply throwing a PageRedirectException, the error can be forwarded onto 
a custom error page. The code below shows the key piece of logic. I took 
this one step further and stored the error information into the request 
for use in the custom error page. This method of passing error 
information also just  happens to match the way servlet containers pass 
data to error pages registered in web.xml.  I now have a single error 
page that works for both purposes.

This approach has already found its way into a couple of production 
applications. If anyone is interested I would be happy to share my code. 
I would also be interested in what other people are doing for their 
Tapestry error pages.

    /*
     * Throws a Page Redirect exception to report that a requested page
     * specification could not be found. The target error page name is
     * the value configured in the application specification file or the
     * default given by DEFAULT_SPECIFICATION_ERROR_PAGE.
     */
    public IComponentSpecification findPageSpecification(IRequestCycle 
cycle,
            INamespace namespace, String simplePageName) {

        // Determine the name of the error page to display
        IApplicationSpecification appSpec = 
cycle.getEngine().getSpecification();
        String errorPageName = 
appSpec.getProperty(SPECIFICATION_RESOLVER_ERROR_PAGE_KEY);

        if (Tapestry.isBlank(errorPageName))
            errorPageName = DEFAULT_SPECIFICATION_RESOLVER_ERROR_PAGE;

        // Handle special case where the error page itself cannot be found
        if (simplePageName.equals(errorPageName))
            return null;

        // Store information about the error in the request
        HttpServletRequest request = cycle.getRequestContext().getRequest();
        HttpServletResponse response = 
cycle.getRequestContext().getResponse();
       
        request.setAttribute("javax.servlet.error.status_code", new 
Integer(HttpServletResponse.SC_NOT_FOUND));
        request.setAttribute("javax.servlet.error.message", "Unable to 
find the requested page");
        request.setAttribute("javax.servlet.error.request_uri", 
request.getRequestURI());
        request.setAttribute("javax.servlet.error.servlet_name", 
request.getServerName());
        request.removeAttribute("javax.servlet.error.exception_type");

        // Set http response code to 404
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
       
        throw new PageRedirectException(simplePageName, null, null, 
errorPageName);
    }


Here is how the class is registered in the application specification:

  <!-- Register an extension to handle missing page errors -->
  <extension name="org.apache.tapestry.specification-resolver-delegate"
             
class="com.extensia.tapestry.engine.SpecificationResolverErrorDelegate"/>




---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org