4

I'm designing an error page for a particular exception type.

<error-page>
    <exception-type>xxx.AbstractConfigurableNotFoundException</exception-type>
    <location>/xxx/page-not-found.xhtml</location>
</error-page>

I am using OmniFaces and their exception factory to handle errors.

<factory>
    <exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandler</exception-handler-factory>
</factory>

AbstractConfigurable is a domain class and its instance is being created during template evaluation*. The constructor of AbstractConfigurable may throw an AbstractConfigurableNotFoundException. When it does, this exception gets wrapped into template-specific exceptions as a cause.

javax.servlet.ServletException
    Caused by: javax.faces.view.facelets.TagAttributeException
         Caused by: com.sun.faces.mgbean.ManagedBeanCreationException
              ...
                   Caused by: xxx.AbstractConfigurableNotFoundException

As a result, a different exception type comes out and my <error-page> logic isn't applied.

Obviously, I don't want to handle, javax.faces.view.facelets.TagAttributeException

<error-page>
    <exception-type>javax.faces.view.facelets.TagAttributeException</exception-type>
    <location>/xxx/page-not-found.xhtml</location>
</error-page>

but I'd like to handle any exception with an AbstractConfigurableNotFoundException as a cause.

Is there anything I can do about it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
  • 1
    This is a really strange example. Custom exception wrapped in a NFE which is in turn wrapped in an IAE. I hope it's just an example? And, I'm confused why you configured an error page location while you're using the `FacesMessageExceptionHandler` instead of `FullAjaxExceptionHandler`. Which one are you really using? The latter has according to its javadoc a `org.omnifaces.EXCEPTION_TYPES_TO_UNWRAP` which could be useful. – BalusC Jul 22 '19 at 11:18

1 Answers1

3

The FullAjaxExceptionHandler supports a context parameter to set fully qualified names of exception types to unwrap. Below is an extract of relevance from its documentation:

Configuration

By default only FacesException and ELException are unwrapped. You can supply a context parameter "org.omnifaces.EXCEPTION_TYPES_TO_UNWRAP" to specify additional exception types to unwrap. The context parameter value must be a commaseparated string of fully qualified names of additional exception types. Note that this also covers subclasses of specified exception types.

<context-param>
    <param-name>org.omnifaces.EXCEPTION_TYPES_TO_UNWRAP</param-name>
    <param-value>javax.ejb.EJBException,javax.persistence.RollbackException</param-value>
</context-param>

This context parameter will also be read and used by FacesExceptionFilter.

So, in your specific case you could use the following configuration in web.xml:

<context-param>
    <param-name>org.omnifaces.EXCEPTION_TYPES_TO_UNWRAP</param-name>
    <param-value>com.sun.faces.mgbean.ManagedBeanCreationException</param-value>
</context-param>

Note that javax.faces.view.facelets.TagAttributeException extends from FacesException, which is by default already unwrapped, so you don't really need to specify this along.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • It was a strange example, indeed... Updated with the real stacktrace. Thank you for the answer. – Andrew Tobilko Jul 22 '19 at 14:11
  • 2
    Right. Answer also updated accordingly. In next questions please don't obfuscate code/logic/behavior which is beyond your control. It would make the question potentially really confusing to experts. – BalusC Jul 22 '19 at 14:46