Custom Exception Pages

One of the most common requests seen on the users mailing list is "how do I replace the default Tapestry exception page with my own custom page?". This section will attemp to clear that up.

Default hivemind configuration

The Tapestry exception presenting logic works by using whatever configuration values are found in the global hivemind tapestry.Infrastructure configuration point to specify which pages to use. (using Page names)

The following fragment is the complete configuration used by the default Tapestry exception presenting services:

<contribution configuration-id="tapestry.Infrastructure">
    <property name="exceptionPageName" value="Exception"/>
    <property name="exceptionPageName" mode="wml" value="WMLException"/>
    
    <property name="staleSessionPageName" value="StaleSession"/>
    <property name="staleSessionPageName" mode="wml" value="WMLStaleSession"/>
    
    <property name="staleLinkPageName" value="StaleLink"/>
    <property name="staleLinkPageName" mode="wml" value="WMLStaleLink"/>
    
    <property name="requestExceptionReporter" object="service:RequestExceptionReporter"/>    
    <property name="exceptionPresenter" object="service:ExceptionPresenter"/>
    <property name="exceptionPresenter" mode="wml" object="service:WMLExceptionPresenter"/>
    
    <property name="staleSessionExceptionPresenter" object="service:StaleSessionExceptionPresenter"/>
    <property name="staleLinkExceptionPresenter" object="service:StaleLinkExceptionPresenter"/>
</contribution>  

Override the core Exception page with your own

Using the configuration reference above we can see that we only need to override the default exceptionPageName configuration property to have our own page used.

So, for example - if you had written a custom page in your application called MyCustomExceptionPage you would be able to make it the default exception page by adding this fragment to your application's hivemodule.xml configuration file:

<contribution configuration-id="tapestry.InfrastructureOverrides">
    <property name="exceptionPageName" value="MyCustomExceptionPageName"/>
</contribution>  

Your page would have to have a property called exception. A sample page class might look as follows:

public abstract class MyCustomExceptionPage extends BasePage
{
    private static Logger logger = Logger.getLogger(ExceptionPage.class);

    @InitialValue("false")
    public abstract boolean isPageNotFound();
    public abstract void setPageNotFound(boolean pageNotFound);
    
    public void setException(Throwable t)
    {
        logger.error("an exception occured", t);
        if(t instanceof PageNotFoundException ||
                t.getCause() instanceof PageNotFoundException)
        {
            setPageNotFound(true);
        }
    }
}