Exception handling is one of the areas were Seam truly improves JSF. Lack of an exception handling facility in JSF was a huge oversight. According to the spec, you were expected to handle exceptions in web.xml. There are two problems with this approach. The first is that exceptions were caught outside of the JSF context. Second was that all you can do is direct the user to an error page, with no opportunity to close database connections, rollback transactions, or any other cleanup you might need to do.
Seam takes both a declarative and event-based approach to exception handling. In the Seam page descriptor (i.e., /WEB-INF/pages.xml), you define any number of <exception> elements, which allow you to declaratively control exception handling. Using that element you can catch an exception and either redirect to an error page with an optional message or send an HTTP error code with optional message.
In Seam 2.1, you can have a message logged.
Another option is to annotate a custom exception with @Redirect or @HttpError, giving you the same control as the page descriptor for redirecting to an error page or sending an http error code, respectively.
By default, Seam will rollback an active transaction when an exception is raised, as well as perform some other internal cleanup work. You can control which exceptions cause a rollback (i.e., disable the default behavior) using the @ApplicationException annotation:
The exception handlers (both XML and annotations) allow you to control whether or not the current long-running conversation should be ended.
That covers the declarative solution. Seam's exception handling facility also keeps observers in the loop. When an exception is captured, Seam raises the org.jboss.seam.exceptionHandled event and when the exception falls through, Seam raises the org.jboss.seam.exceptionNotHandled event.
Keep in mind when testing your exception handlers that if you are running Facelets in development mode, the debug page might trap the exception before it gets to the Seam exception handler.