Handling exceptions

Overview

While generally it's best to handle exceptions in as low-level as possible to avoid expensive exception chains and to shield the rest of your system from side effects, there are times when you want your user interface layer to handle known and expected exceptions. These often involve errors in fetching data or security errors in which cases you may need to inform the user of the reason for an operation failure. Tapestry catches all exception and by default presents its own error page, so the standard servlet exception pages using error-page elements with nested exception-type elements in your web.xml won't work. Tapestry's default exception page is extremely useful in development, but not so nice in production. Via Hivemind configuration, Tapestry allows you to contribute a custom ExceptionPresenter and override the default one. It's still not quite as flexible as the specification that allows different error pages for specific exception types. In Hivemind 1.1.2 the exception handling was changed to a pipeline that would have allowed this, but unfortunately Hivemind 1.1.2 was never released.

Default exception handling in Trails

Trails provides a custom implementation for a ExceptionPresenter that displays a page called DefaultException. Following the Trails page resolving model, if the type of entity that was being handled was known when an error happened and a exception page for that specific type exists (named <Type>Exception, e.g. ReceipeException), that page will be displayed instead. A type is generally known when a user tries to do an illegal operation, such as update or remove, on an existing object. While this provides, some flexibility, it's still not far from ideal where you could easily create custom pages for specific type and operation. However, because of the aforementioned issues with Hivemind, this is not currently possible. For the same reasons, Trails _ApplicationExceptionPresenter is declared in the Hivemind configuration of trails-core, but the contribution is not. In the examples or when you create a Trails project using the archetype the contribution is declared in your application's hivemind so can you easily change it if you prefer to implement your own. Specifically, these two contributions are declared by default:

<contribution configuration-id="tapestry.InfrastructureOverrides">
  <property name="exceptionPresenter" object="service:trails.core.ApplicationExceptionPresenter"/>
</contribution>
<contribution configuration-id="tapestry.InfrastructureOverrides">
  <property name="exceptionPageName" value="DefaultException"/>
</contribution>

Note that our custom ExceptionPresenter extends Tapestry default ExceptionPresenterImpl and so it's meant to handle Trails specific error pages with a user-friendly page and delegate other exceptions to the default one. However, by default the exception page used (the latter contribution) is the same one that will be used by ApplicationExceptionPresenter when the entity type is not known or an entity specific exception page is not available.

Future improvements

Clearly, an exception pipeline is a superior implementation. Even without the Hivemind changes described, it can done by first implementing a ExceptionPresenter that implements an interface that use the Exception type as the first parameter in it's method signature. It's likely this will be implemented in Trails 1.2.

Labels

 
(None)