The standard Servlet mechanism for handling exceptions that occur on the server is to specify an error-page entry in the deployment descriptor (web.xml file) and allow the container to redirect to the configured resource. For example:
This mechanism works fine as long as the exception makes it up to the servlet container. If the exception is handled in some other way and doesn't bubble up to the container, it renders the error-page strategy ineffective.
With JSF 2 and ICEfaces, you can decide how you want to handle exceptions both on the server and the client.
With JSF 2, there is now a facility for hooking into the lifecycle and customizing how exceptions are handled. This is done using an ExceptionHandlerFactory and one or more custom ExceptionHandlers. By default, Mojarra provides implementations of both a standard ExceptionHandler for normal requests as well as an Ajax implementation for Ajax requests
Exceptions for non-Ajax requests can be handled using the error-page facility. If no error page is specified then a default page is created JSF and sent back to the client.
Exceptions for Ajax requests are contained within Ajax responses and do not trickle up to the container so the error-page strategy is not used.
If you'd like to change this behavior in some way, you can write your own ExceptionHandler and deal with the exceptions on the server as you see fit. It's relatively simple to do. ICEfaces currently uses the technique described here to emit SessionExpired exceptions instead of ViewExpiredExceptions when appropriate.
ExceptionHandlers are request-scoped resources - that is, there is a new one for each request. Exceptions that occur during a JSF lifecycle are generally queued to be handled by one or more of the ExceptionHandlers. Normally, you'd create an ExceptionHandler that extends ExceptionHandlerWrapper. The interesting work of finding the exceptions you're interested in and then processing those might look like this:
ExceptionHandlers are created by ExceptionHandlerFactories. The basic mechanism is to create an ExceptionHandlerFactory that links into the chain of existing ExceptionHandlerFactories. Your factory is used to create the appropriate ExceptionHandler for the request. Because it's a wrapper, we can chain them together by passing in the delegate when we create the instance. For example:
3) Then you need to register your factory with JSF. You can add an entry into the faces-config.xml of the .war that includes your custom ExceptionHandler(s):
ICEfaces uses this same technique. By default, when ICEfaces is active on the page and an error comes back as an Ajax response, a small popup is displayed with a short description of the error. For example, if a session times out and you attempt to interact with the page it will cause a ViewExpiredException when JSF attempts to restore the view:
If you would like to do something else with these errors, you can use much the same technique as described above:
When any of the default popups comes up there is also a transparent overlay rendered underneath. This overlay has a CSS class assigned so that it can be styled in concordance with the rest of the application. By default the CSS styles are as follows:
Providing a stylesheet with new definitions for ice-status-indicator-overlay CSS class should be enough to override the default styling.
© Copyright 2021 ICEsoft Technologies Canada Corp.