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