3
votes

In our project we are using PrimeFaces 3.3 along with OmniFaces FullAjaxExceptionHandler as described in this blog.

It works very well for all Ajax calls, except for exceptions in our implementation of the load() method in the class that extends PrimeFaces LazyDataModel. After an exception is thrown in the load() method, it's not showing up in the iterator in the handleAjaxException() method of the FullAjaxExceptionHandler class:

Iterator<ExceptionQueuedEvent> unhandledExceptionQueuedEvents = getUnhandledExceptionQueuedEvents().iterator();

All other exceptions thrown in Ajax calls end up in the iterator.

I compared stack traces and that's what I found: when using PrimeFaces lazy loading, the stack trace shows that it occurred during render response phase:

at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:391)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)

Non-lazy loading errors occur during invoke application phase:

at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)

I have the following questions:

  1. Is the reason that FullAjaxExceptionHandler doesn't catch the exception because it is thrown too late in the lifecycle?
  2. Is it a PrimeFaces bug?
1

1 Answers

3
votes

I wouldn't call it a bug, but it's a bit unfortunate design, that the lazy model is invoked by FilterFeature, which is invoked by encode* methods in render phase.

In JSF, your business logic code (such as fetching data) is expected to be launched in application phase, so it's not suprising, that many features don't work with lazy loading. One of other things that is not working is requesting component update in code:

RequestContext.getInstance().update("componentId")

In order to update component, I've had to add JavaScript call:

RequestContext.getInstance().execute("triggerUpdate('componentId')")

In your case, adding JavaScript call may be a viable work-around. JavaScript calls are simply added to response XML, so they work in each phase (which enabled to solve my case - requesting update).