PrimeFaces provides a powerful ExceptionHandler out of the box with following features:
<div class="card">
<h:form>
<h5 class="mt-0">AJAX</h5>
<p:commandButton action="#{exceptionHandlerView.throwViewExpiredException}"
ajax="true"
value="Throw ViewExpiredException!" styleClass="mr-2" />
<p:commandButton action="#{exceptionHandlerView.throwNullPointerException}"
ajax="true"
value="Throw NullPointerException!"/>
<!-- IllegalStateException is not handled using ajaxExceptionHandlers below, so the error page is shown-->
<p:commandButton action="#{exceptionHandlerView.throwWrappedIllegalStateException}"
ajax="true"
value="Throw IllegalStateException!" styleClass="mr-2"/>
<h5>Non-AJAX</h5>
<p:commandButton action="#{exceptionHandlerView.throwViewExpiredException}"
ajax="false"
value="Throw ViewExpiredException!" styleClass="mr-2"/>
<!-- NullPointerException has no specific error-page defined in web.xml compared to ViewExpiredException -->
<!-- https://github.com/primefaces/primefaces/blob/master/primefaces-showcase/src/main/webapp/WEB-INF/web.xml -->
<p:commandButton action="#{exceptionHandlerView.throwNullPointerException}"
ajax="false"
value="Throw NullPointerException!"/>
<p:ajaxExceptionHandler type="jakarta.faces.application.ViewExpiredException"
update="exceptionDialog"
onexception="PF('exceptionDialog').show()" />
<p:ajaxExceptionHandler type="java.lang.NullPointerException"
update="exceptionDialog"
onexception="PF('exceptionDialog').show()"/>
<p:dialog id="exceptionDialog" header="Exception '#{pfExceptionHandler.type}' occured!"
widgetVar="exceptionDialog"
height="500px">
Message: #{pfExceptionHandler.message} <br/>
StackTrace: <h:outputText value="#{pfExceptionHandler.formattedStackTrace}" escape="false"/> <br/>
<p:button onclick="document.location.href = document.location.href;"
value="Reload!"
rendered="#{pfExceptionHandler.type == 'jakarta.faces.application.ViewExpiredException'}"/>
</p:dialog>
</h:form>
</div>
package org.primefaces.showcase.view.misc;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.FacesException;
import jakarta.faces.application.ViewExpiredException;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Named;
import io.quarkus.runtime.annotations.RegisterForReflection;
@Named
@RequestScoped
@RegisterForReflection(serialization = true)
public class ExceptionHandlerView {
public void throwNullPointerException() {
throw new NullPointerException("A NullPointerException!");
}
public void throwWrappedIllegalStateException() {
Throwable t = new IllegalStateException("A wrapped IllegalStateException!");
throw new FacesException(t);
}
public void throwViewExpiredException() {
throw new ViewExpiredException("A ViewExpiredException!",
FacesContext.getCurrentInstance().getViewRoot().getViewId());
}
}