Random bits of information by a developer

24 November 2010

Seam Catch Release

Seam Catch Alpha1 was released yesterday! You can read about ithere, or the docs. Bits can be found in the JBossrepository using maven:
<dependency>
    <groupId>org.jboss.seam.catch</groupId>
    <artifactId>seam-catch-api</groupId>
    <version>3.0.0.Alpha1</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.jboss.seam.catch</groupId>
    <artifactId>seam-catch-impl</groupId>
    <version>3.0.0.Alpha1</version>
    <scope>runtime</scope>
</dependency>
Or at SourceForge. I'm very interested in any feedback that you may have.

What is Catch?

Catch is the exception handling infrastructure in Seam3. I like to refer to it as Next Generation Exception Handling. It really goes beyond what was available in Seam2 and offers a complete solution for Exception Handling. It's built on top of CDI events so the entry point is very minimal and usage is quite easy.

Usage

For those who are familiar with CDI events, creating your own handlers will be very familiar. Handlers are quite similar to CDI Observers, though there are a few differences:
  1. handlers must be contained in a bean marked by @HandlesExceptions
  2. the first parameter in the method must be annotated with @Handles and be an instance of CaughtException&lt;T extends Throwable>
  3. handlers are ordered before they're invoked
Keep those things in mind and the rest is very easy.

Creating a Handler

The docs really cover this very well, but here's a simple handler to get you started:
@HandlesExceptions
public class JsfHandlers {
    public void redirectingHandler(@Handles(precedence = -100) CaughtException<Throwable> event, NavigationHandler nav) {
        nav.handleNavigation(FacesContext.getCurrentInstance(), null, "/error.xhtml");
    }
}
NOTE: The best way to tie this handler into JSF is by adding a JSF to Catch bridge by creating an ExceptionHandler (this will be added to Catch in the next release, as a separate jar) to fire the ExceptionToCatchEvent.

There's not much there as you can see. We're saying this is a general handler (the CaughtException type is Throwable) and we want it run towards the end of the cause container traversal (precedence = -100). If you're not familiar with JSF, this is will navigate the user to the error page at the end of the exception handling. Of course this would require some extra JSF integration pieces to produce the NavigationHandler such as Seam Faces or Apache CODI, or your own producer. The NavigationHandler is injected via CDI, in fact, any additional parameters past the CaughtException param will be injected for you. Anything that you need for your exception handling, as long as CDI can create it, can be injected for you.

Entering Catch

Above I mentioned the ExceptionToCatchEvent. This event is all that's needed to start the handling process. Something as simple as
@Inject Event<ExceptionToCatchEvent> catchEvent;
...
try {
    your code
} catch (Exception e) {
    catchEvent.fire(new ExceptionToCatchEvent(e));
}
will get the ball rolling.

That's really all there is to it! I'm looking forward to any feedback you may have, and bugs if you find them. Bugs should be filled in JIRA. In the next release look for bridges for JSF, JAX-RS and others, and the ability to filter stack traces!

2 comments:

Unknown said...

Nice, looks easy to use! I can't wait until Weld 1.1 is available in GF 3.1 to try it out.

You blog doesn't mention unchecked exceptions. Are those handled as well?

Unknown said...

Yes, unchecked exceptions work as well. Everytime an exception is referenced in the code, it's a Throwable so we can handle everything. All integration points should work with Throwable. You can also see in the tests where I use both checked and unchecked exceptions.

As for it working in GF 3.1 if you have tests or apps where things don't work please send them to the GF guys and Pete. We have next to nothing for GF tests in the codebase :(