5

Following my previous question in Creating FacesMessage in action method outside JSF conversion/validation mechanism? , i'm trying to handle the exceptions thrown from the business layer outside my managed beans.

The strategy is to search and convert business exceptions to faces messages in the a PhaseListener,.

It is working as i expected, but im just wondering if im just reinventing the wheel, or doing it right with the wrong way ?

Here's my code sample snippet :

public class BusinessExceptionHandler implements PhaseListener {

    @Override
    public void afterPhase(PhaseEvent phaseEvent) {
        ExceptionHandler exceptionHandler = phaseEvent.getFacesContext().getExceptionHandler();

        // just debugging the handled exception, nothing here
        /*
        for (ExceptionQueuedEvent event : exceptionHandler.getHandledExceptionQueuedEvents()) {
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
            System.out.println("handled exception : " + context.getException());
        }*/

        for (Iterator<ExceptionQueuedEvent> it = exceptionHandler.getUnhandledExceptionQueuedEvents().iterator(); 
                it.hasNext();) {

            ExceptionQueuedEvent event = it.next();
            ExceptionQueuedEventContext eventContext = (ExceptionQueuedEventContext) event.getSource();
            Throwable e = eventContext.getException();
            System.out.println("unhandled exception : " + e);

            // get the root cause exception
            while (e.getCause() != null) { 
                e = e.getCause();
            }

            System.out.println("cause exception : " + e + 
                ", cause exception is BE : " + (e instanceof BusinessException));

            // handle BE
            if (e instanceof BusinessException) {
                BusinessException be = (BusinessException) e;
                System.out.println("processing BE " + be);
                FacesMessage message = Messages.getMessage(
                    "com.corejsf.errors", 
                    be.getMessage(), 
                    be.getParamValues()
                );
                FacesContext context = FacesContext.getCurrentInstance();
                context.addMessage(null, message);
                it.remove(); // remove the exception

                // works fine without this block, if BE is thrown, always return to the original page
                /*
                NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
                System.out.println("navigating to " + context.getViewRoot().getViewId());
                navigationHandler.handleNavigation(context, context.getViewRoot().getViewId(), null);
                */
            }
        }
    }

    @Override
    public void beforePhase(PhaseEvent phaseEvent) {
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.INVOKE_APPLICATION;
    }

}

Thank you !

Regards, Albert Kam

Community
  • 1
  • 1
Bertie
  • 17,277
  • 45
  • 129
  • 182

2 Answers2

3

Not sure why you're going this route, creating and registering your own exception handler is really easy. Though easier will be Seam Catch ( http://seamframework.org/Seam3/CatchModule and http://docs.jboss.org/seam/3/catch/3.0.0.Alpha1/reference/en-US/html_single/ ). I don't have a JSF bridge just yet, but it will be very easy to do. Then all you have to do is write one method that will handle a specific exception, and you'll be done!

LightGuard
  • 5,298
  • 19
  • 19
  • Im still new to the jsf and full of doubts about the best practices, hence the question above :) Thanks for the suggestion, though im not using seam framework, im gonna take a look about the exception handler api. – Bertie Nov 29 '10 at 12:22
2

Your approach is an intermix of JSF 1.x and JSF 2.x exception handling approaches. Since you're using JSF 2.x, I'd suggest a pure JSF 2.x approach without a PhaseListener and with help of the new ExceptionHandler API.

You can find an example which treats the ViewExpiredException in page 282 of the book "JSF 2.0: The Complete Reference" which is online available here (click the 1st result link).

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hi again. Thanks for the idea. The page 282 is not available. But after some googling, i found edburn's article about this kind of matter, and will use this practice later : http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2 – Bertie Nov 29 '10 at 12:29