Fórum

PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

thumbnail
Oleg Efimov, modificado 9 Anos atrás.

PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

New Member Postagens: 21 Data de Entrada: 10/07/14 Postagens Recentes
Hi,

I'm trying to use PrimeFaces error handling mechanism under Liferay and Faces Bridge.

I've created a simple app (available in attachment) based on Liferay 6.2 CE GA2, Faces Bridge 4.2.0-m1, Mojarra 2.2.10, PrimeFaces 5.1.

... with a facelet:

        <p:ajaxexceptionhandler update="exceptionDialog" onexception="PF('exceptionDialog').show();" />

        <p:dialog id="exceptionDialog" header="Error" widgetvar="exceptionDialog" closeonescape="true" modal="true" resizable="false" draggable="false">
            <p:panelgrid id="exception-panel" columns="1" styleclass="ui-state-error" columnclasses="ui-state-error">
                <p:outputlabel styleClass="ui-state-error-text" value="Some error! Contact administrator, please." />
                <p:outputlabel styleClass="ui-state-error-text" rendered="#{pfExceptionHandler.exception != null}" value="Technical Details: #{pfExceptionHandler.formattedTimestamp} #{pfExceptionHandler.type} #{pfExceptionHandler.message}" />
            </p:panelgrid>
        </p:dialog>

        <p:log />

        <h:form id="form-test-error">
            <p:commandbutton value="Action Error" action="#{testError.causeActionError}" ajax="false" />
            <p:commandbutton value="Action Error AJAX" action="#{testError.causeActionError}" update="label" />
            <p:commandbutton value="Render Error" action="#{testError.causeRenderError}" ajax="false" />
            <p:commandbutton value="Render Error AJAX" action="#{testError.causeRenderError}" update="label" />

            <p:outputlabel id="label" value="#{testError.status}" />
        </h:form>


... and a bean:

@ManagedBean(name = "testError")
@SessionScoped
public class TestErrorController {
    protected boolean throwRenderException;

    public void causeActionError() {
        throw new IllegalArgumentException("Deliberate action exception");
    }

    public void causeRenderError() {
        throwRenderException = true;
    }

    public String getStatus() {
        if (throwRenderException) {
            throwRenderException = false;
            throw new IllegalArgumentException("Deliberate render exception");
        } else {
            return "Updated at " + new Date();
        }
    }
}


This app works correctly in servlet environment:
  • Non-ajax action error -> redirect to error page
  • Non-ajax render error -> inlined error page
  • Both ajax errors -> error dialog


However in portlet environment Ajax render error (the last button) is not processed correctly -- error is seen in server trace, but no dialog is shown.

I've investigated the problem a little:
  • PrimeFaces log element says that Ajax response from server couldn't be parsed
  • Ajax response is malformed and contains two XML roots (partial-response elements) -- first for decent update (in our case, 'label' component), second for exception handler update
  • PrimeExceptionHandler (line 134) relies on ExternalContext.reset to clear decent update output before writing its own
  • In Faces Bridge this call results in no-op (ExternalContextCompat_2_0_Impl:253 -> com.liferay.portlet.MimeResponseImpl:124)


Any further help is highly appreciated!

P.S. Even more depressing is that upgrade to PrimeFaces 5.2 stops Ajax action error from working correctly; upgrade to Faces Bridge 4.2.0-m2 breaks non-Ajax action error.
thumbnail
Vernon Singleton, modificado 9 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

Expert Postagens: 315 Data de Entrada: 14/01/13 Postagens Recentes
Hi Oleg,

Oleg Efimov:
I'm trying to use PrimeFaces error handling mechanism under Liferay and Faces Bridge.

I've created a simple app (available in attachment) based on Liferay 6.2 CE GA2, Faces Bridge 4.2.0-m1, Mojarra 2.2.10, PrimeFaces 5.1.

I have also created such a sample app, but mine uses Faces Bridge 4.2.0-rc1-SNAPSHOT, mojarra.version 2.2.6, primefaces 5.2

Oleg Efimov:

This app works correctly in servlet environment:
  • Non-ajax action error -> redirect to error page
  • Non-ajax render error -> inlined error page
  • Both ajax errors -> error dialog


I am getting the same results.

Oleg Efimov:

However in portlet environment Ajax render error (the last button) is not processed correctly -- error is seen in server trace, but no dialog is shown.

I am seeing this same issue, so I opened an issue and sent a pull request to the folks at PrimeFaces to fix this issue.
Let's see if they can get this fix into the next version of PrimeFaces. If you happen to have support from PrimeFaces, could you please let us know, and up vote the pull request?

Oleg Efimov:

Any further help is highly appreciated!

Also you stated you are not using version 2.2.6 or 2.2.8 of Mojarra ... why are you using 2.2.10?

Oleg Efimov:
P.S. Even more depressing is that upgrade to PrimeFaces 5.2 stops Ajax action error from working correctly; upgrade to Faces Bridge 4.2.0-m2 breaks non-Ajax action error.

Was there a previous version of PrimeFaces where the PrimeFaces ExceptionHandler was working correctly? If so, which version was that? I tested the fix I submitted to the PrimeFaces folks with our 4.2 snapshot version. But since you are using m2, checkout Neil's blog post from this morning, and try out the beta (or rc1).

Hope that helps,
Vernon
thumbnail
Oleg Efimov, modificado 9 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

New Member Postagens: 21 Data de Entrada: 10/07/14 Postagens Recentes
Hi Vernon,

Many thanks for your quick reply.

Vernon Singleton:
I am seeing this same issue, so I opened an issue and sent a pull request to the folks at PrimeFaces to fix this issue.
Let's see if they can get this fix into the next version of PrimeFaces. If you happen to have support from PrimeFaces, could you please let us know, and up vote the pull request?

Unforunately, no emoticon

Vernon Singleton:
Also you stated you are not using version 2.2.6 or 2.2.8 of Mojarra ... why are you using 2.2.10?

Actually I'm using MyFaces (and slightly patched Liferay Faces -- see this thread), so I've just taken the latest Mojarra for the reproducer, knowing that you support this implementation. Are only 2.2.6 and 2.2.8 versions supported at the moment?

Vernon Singleton:
Was there a previous version of PrimeFaces where the PrimeFaces ExceptionHandler was working correctly? If so, which version was that? I tested the fix I submitted to the PrimeFaces folks with our 4.2 snapshot version. But since you are using m2, checkout Neil's blog post from this morning, and try out the beta (or rc1).

I've only checked PF 5.1 and 5.2, don't know if it worked in 5.0. Thanks, I'll test Liferay Faces beta + PrimeFaces 5.2 + your patch and report the result here!

Cheers,
Oleg.
thumbnail
Vernon Singleton, modificado 9 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

Expert Postagens: 315 Data de Entrada: 14/01/13 Postagens Recentes
Hi Oleg,

Looks like they merged the commit. So it would probably be available in 5.3 or their current snapshot.

Hope that helps,
Vernon
thumbnail
Oleg Efimov, modificado 9 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

New Member Postagens: 21 Data de Entrada: 10/07/14 Postagens Recentes
Hi Vernon,

I've tested the patch (PrimeFaces 5.2, Bridge 4.2.0-beta, Mojarra 2.2.6) -- it does fix AJAX ACTION case.
However, AJAX RENDER still doesn't work -- because problems listed in my first post weren't addressed.

Once again:
  • When PrimeErrorHandler requests ExternalContext reset, it's not done -- see com.liferay.portlet.MimeResponseImpl#reset (:124), _response.reset is not called!
  • Even if reset is called, PrimeErrorHandler#handleAjaxException uses PartialResponseWriter which wasn't reset and is in the middle of witing -- it has to be reset, too.


I've tested some ugly patches:
  • Overriden ResourceResponseBridgeLiferayImpl#reset to call ((LiferayPortletResponse) getResponse()).getHttpServletResponse().reset();
  • Overriden PrimeErrorHandler#handleAjaxException to clear 'writer' fields (yep, via reflection) of all PartialResponseContext hierarchy in addition to ExternalResponse context -- this way writers are recreated when requested by PrimeErrorHandler.

In order for reset to work I've also had to turn off gzip filter (com.liferay.portal.servlet.filters.gzip.GZipFilter=false).

With those (ugly) patches, everything works fine (all 4 error cases).

Could you please comment on this? emoticon

Cheers,
Oleg.
thumbnail
Vernon Singleton, modificado 8 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

Expert Postagens: 315 Data de Entrada: 14/01/13 Postagens Recentes
Hi Oleg,

Sorry I have not gotten back to this ... getting ready for the next release :-)

I this still an issue in your environment?

- Vernon
thumbnail
Oleg Efimov, modificado 8 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

New Member Postagens: 21 Data de Entrada: 10/07/14 Postagens Recentes
Hi Vernon,

Great to see you back! emoticon

Yes, the issue is actual, we're using (ugly) patches I've mentioned above as a workaround.

Cheers,
Oleg.
Edward Chen, modificado 8 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

New Member Postagens: 3 Data de Entrada: 18/01/15 Postagens Recentes
Hi Oleg,

Thanks for your effort to resolving this issue.
I've tested on Primefaces-5.3-snapshot, Bridge 4.2.5-ga6-snapshot, Mojarra 2.2.8. Howerver, there is no luck for Ajax Render Exception.
May I have your patched code for it? That will do me a great favor.
By the way, will it merge into next release of Primfeaces and Liferay Bridge?

Best Regards,
Edward
thumbnail
Vernon Singleton, modificado 8 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

Expert Postagens: 315 Data de Entrada: 14/01/13 Postagens Recentes
Hi Oleg,

I am still working on this issue. Thank you for pointing this issue out, it is teaching me many things that I need to know about JSF.
But I have two questions:

1. Did you try using the PrimeExceptionHandler in a normal webapp?
2. Did you set the javax.faces.FACELETS_BUFFER_SIZE parameter?

The reason I ask, is that I just noticed this in the PrimeFaces documentation:
primefaces user guide:
To support exception handling in the RENDER_RESPONSE phase, it's required to set the javax.faces.FACELETS_BUFFER_SIZE parameter. Otherwise you will probably see a ServletException with "Response already committed" message.

Just curious.
thumbnail
Oleg Efimov, modificado 8 Anos atrás.

RE: PrimeFaces ajaxExceptionHandler fails under Liferay Faces Bridge

New Member Postagens: 21 Data de Entrada: 10/07/14 Postagens Recentes
Hi Vernon,

1. Yes, it worked correctly (I've described it in the initial post "This app works correctly in servlet environment")
2. Yes, to no effect (tried value of 32768, which is much greater than AJAX response size)

HTH,
Oleg.