JSF: no se puede ver ViewExpiredException

Estoy desarrollando una aplicación JSF 2.0 en Glassfish v3 y estoy tratando de manejar la ViewExpiredException. Pero haga lo que haga, siempre recibo un informe de error de Glassfish en lugar de mi propia página de error.

Para simular la aparición del VEE, inserté la siguiente función en mi bean de respaldo, que activa el VEE. Estoy activando esta función desde mi página JSF a través de un enlace de comando. El código:

@Named
public class PersonHome {
  (...)
  public void throwVEE() {
    throw new ViewExpiredException();
  }
}

Al principio lo probé simplemente agregando una página de error a mi web.xml:

<error-page>
  <exception-type>javax.faces.application.ViewExpiredException</exception-type>
  <location>/error.xhtml</location>
</error-page>  

Pero esto no funciona, no se me redirige al error, pero se me muestra la página de error Glassfish, que muestra una página HTTP Status 500 con el siguiente contenido:

description:The server encountered an internal error () that prevented it from fulfilling this request.
exception: javax.servlet.ServletException: javax.faces.application.ViewExpiredException
root cause: javax.faces.el.EvaluationException:javax.faces.application.ViewExpiredException
root cause:javax.faces.application.ViewExpiredException

Lo siguiente que intenté fue escribir ExceptionHandlerFactory y CustomExceptionHandler, como se describe enJavaServerFaces 2.0 - La referencia completa. Así que inserté la siguiente etiqueta en faces-config.xml:

<factory>
  <exception-handler-factory>
    exceptions.ExceptionHandlerFactory
  </exception-handler-factory>
</factory>

Y agregó estas clases: La fábrica:

package exceptions;

import javax.faces.context.ExceptionHandler;

public class ExceptionHandlerFactory extends javax.faces.context.ExceptionHandlerFactory {

    private javax.faces.context.ExceptionHandlerFactory parent;

    public ExceptionHandlerFactory(javax.faces.context.ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        ExceptionHandler result = parent.getExceptionHandler();
        result = new CustomExceptionHandler(result);
        return result;
    }

}

El manejador de excepciones personalizado:

package exceptions;

import java.util.Iterator;

import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

class CustomExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler parent;

    public CustomExceptionHandler(ExceptionHandler parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return this.parent;
    }

    @Override
    public void handle() throws FacesException {
        for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
            ExceptionQueuedEvent event = i.next();
            System.out.println("Iterating over ExceptionQueuedEvents. Current:" + event.toString());
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
            Throwable t = context.getException();
            if (t instanceof ViewExpiredException) {
                ViewExpiredException vee = (ViewExpiredException) t;
                FacesContext fc = FacesContext.getCurrentInstance();

                NavigationHandler nav =
                        fc.getApplication().getNavigationHandler();
                try {
                    // Push some useful stuff to the flash scope for
                    // use in the page
                    fc.getExternalContext().getFlash().put("expiredViewId", vee.getViewId());

                    nav.handleNavigation(fc, null, "/login?faces-redirect=true");
                    fc.renderResponse();

                } finally {
                    i.remove();
                }
            }
        }
        // At this point, the queue will not contain any ViewExpiredEvents.
        // Therefore, let the parent handle them.
        getWrapped().handle();
    }
}

Pero TODAVÍA NO soy redirigido a mi página de error, obtengo el mismo error HTTP 500 como el anterior. ¿Qué estoy haciendo mal? ¿Qué podría faltar en mi implementación de que la excepción no se maneje correctamente?Alguna&nbsp;ayuda muy apreciada!

EDITAR

Ok, soy honesto De hecho, mi código está escrito en Scala, pero esa es una larga historia. Pensé que era un problema de Java todo el tiempo. El error REAL en este caso fue mi propia estupidez. En mi código (Scala), en CustomExceptionHandler, olvidé agregar la línea con "i.remove ();" Por lo tanto, ViewExpiredException permaneció en UnhandledExceptionsQueue después de manejarlo, y "burbujeó". Y cuando aparece, se convierte en una excepción Servlet.

¡Lamento mucho confundirlos a los dos!