Search code examples
javajsfjsf-2spring-elomnifaces

FullAjaxExceptionhandler only catches javax.el.ELException or java.lang.Throwable


FullAjacExceptionHandler can only catch javax.el.ELException or java.lang.Throwable. Throwable also takes precedence over javax.el.ELException. I need to explicit catch a particular exception thrown by the managed bean. However, the ELException apparently wraps the root cause exception (i.e. LoginFailedException).

I'm using JSF 2 (MyFaces 2.1.10), Spring EL resolver (Spring managed beans), el-api-2.2 and glassfish el-impl-2.2.

Here's the error:

Ajax request: No
Status code: 500
Exception type: class org.apache.myfaces.view.facelets.el.ContextAwareELException
Exception message: javax.el.ELException: org.tests.omnifaces.exception.LoginFailedException: Login failed.
Stack trace: org.apache.myfaces.view.facelets.el.ContextAwareELException: javax.el.ELException: org.tests.omnifaces.exception.LoginFailedException: Login failed.
...

LoginFailedException is a simple custom exception. I would appreciate any help. Thanks in advance.

EDIT: experiment done:

I created 3 error pages to see which one will be called/used when LoginFailedException is thrown. The XHTML error pages contain exactly the same code except for the header String that identifies which is which. Here's the web.xml error entries:

<error-page>
    <exception-type>org.tests.omnifaces.exception.LoginFailedException</exception-type>
    <location>/pages/errors/loginError.xhtml</location>
</error-page>

<error-page>
    <exception-type>javax.el.ELException</exception-type>
    <location>/pages/errors/elException.xhtml</location>
</error-page>

<error-page>
   <exception-type>java.lang.Throwable</exception-type>
   <location>/pages/errors/catchAllThrowable.xhtml</location>
</error-page>

catchAllThrowable.xhtml will be used. If i remove(comment out on web.xml) Throwable , ELException.xhtml will be used. If i remove ELException, The exception will be handled by the container (tomcat) and not by loginError.xhtml.

Hope this clarifies my case.

UPDATE:

I am now using AJAX call to submit form (I suppose this is what the handler is intended for) with all 3 error handler pages active on web.xml (Throwable, ELException, LoginFailedException):

<h:commandButton id="loginButton" value="Login" action="#{login.loginUser}">
    <f:ajax execute="@form" render="@form messages" />
</h:commandButton>

The Throwable has been skipped, and the ELException was matched (elException.xhtml rendered). Still not able to zero in on LoginFailedException.


Solution

  • The FullAjaxExceptionHandler only unwraps root causes of FacesException. However, the MyFaces ContextAwareELException isn't a subclass of FacesException, instead it is a subclass of ELException and hence remains un-unwrapped.

    As per OmniFaces issue 149, the FullAjaxExceptionHandler is been improved to unwrap ELException as well. This is available since OmniFaces 1.4.