Handle exception thrown from a CDI interceptor as a faces message

949 Views Asked by At

I want to show exception message in xhtml. Execption is generated in interceptor.

Interceptor class :

    @Logable
    @Interceptor
    public class LoggingInterceptor
    {
        @AroundInvoke
        public Object log(InvocationContext ctx)
            throws Exception {
            if (some logic)
                FacesContext.getCurrentInstance().addMessage("newBandForm:ABCD", new FacesMessage(FacesMessage.SEVERITY_ERROR, "hklfhfhsf", "hklfhfhsf"));
                throw new Exception("MNOP");
            return ctx.proceed();
    }

Action Bean Class

@Named("bcontroller")
@RequestScoped
public class BandListController
{
   @Logable
    public void save()
    {
    }
}

I want to show exception in xhtml p:message

<h:form id="newBandForm">
    <p:messages id="ABCD" autoUpdate="false" closable="true" showDetail="false" escape="false"/>
</h:form>

If I write following line in Action "save()" itself, and remove Interceptor, then message i getting displayed.

   FacesContext.getCurrentInstance().addMessage("newBandForm:ABCD", new FacesMessage(FacesMessage.SEVERITY_ERROR, "hklfhfhsf", "hklfhfhsf"));

It seems that exception thrown is interrupting life-cycle of JSF components also.
thanks

Detail Requirement:

I have one xhtml page which contain one field (say : F1 )and two commandButton (say : C1 and C2). For C1 button, F1 is mandatory and For C2, it is not. This is completely configurable and at bean initialization, I fetch data from database for which button, what fields are mandatory.

Now on finding @Logable annotation, I am invoking interceptor method for checking data consistency based on action. In case validation failed, I have to set p:message (for which I am accessing FaceContext).

Why am i doing like this? So that a single annotation can enable security without changing code of main action.

I end up with in javax "interceptor" after searching "aop in JSF". I do not have option of implementing spring-aop in project.

1

There are 1 best solutions below

0
On BEST ANSWER

My lack of understanding about "ctx.proceed()" lead me to this problems.What it do is "Proceed to the next interceptor in the interceptor chain." and if there is non, flow will resume as usual.

(Workaround) Changing code like this solve my issue:

@AroundInvok
public Object log(InvocationContext ctx)
    throws Exception {
    if (!(some logic))
    {
        return ctx.proceed();
    }
    else
    {
        FacesContext.getCurrentInstance().addMessage("newBandForm:ABCD", new FacesMessage(FacesMessage.SEVERITY_ERROR, "hklfhfhsf", "hklfhfhsf"));
        return null;
    }   
}

Now I am not throwing any exception from it.