Simplified, my error handler looks like this:
@Override
public void handle() throws FacesException {
Iterator unhandledExcept
You should not use ExternalContext#dispatch()
to render a JSF view. It should only be used to forward to a non-JSF resource. You should instead set the desired JSF view by FacesContext#setViewRoot() and let JSF render it.
ViewHandler viewHandler = context.getApplication().getViewHandler();
UIViewRoot viewRoot = viewHandler.createView(context, viewId);
context.setViewRoot(viewRoot);
context.renderResponse();
Or, if you're currently already sitting in the render response, then it's too late to let JSF re-render it. You'd need to build and render the new view manually. In that case, replace the last line by:
ViewDeclarationLanguage vdl = viewHandler.getViewDeclarationLanguage(context, viewId);
vdl.buildView(context, viewRoot);
context.getApplication().publishEvent(context, PreRenderViewEvent.class, viewRoot);
vdl.renderView(context, viewRoot);
context.responseComplete();
Note that this is in turn too late if the response is already committed. You may want to check that beforehand as well.
You may find the source code of the OmniFaces FullAjaxExceptionHandler helpful to get some insight.