4.7. Controlar Errores

4.7.1 Indicador y mensaje de Error

Todos los componentes tienen un indicador de error incorporado que se puede establecer explícitamente con setComponentError() o se puede activar implícitamente si la validación del componente falla. Como con el componente caption, la ubicación del indicador es manejado por el diseño en el que se encuentre el componente. Por lo general, el indicador de error es ubicado a la derecha del texto del título. Al pasar el puntero del ratón sobre el campo muestra el mensaje de error.

El siguiente ejemplo muestra cómo se puede establecer el error del componente de forma explícita. El ejemplo básicamente valida el valor del campo sin necesidad de utilizar un validador actual.

// Crear un campo.
final TextField campoTexto = new TextField("Introduzca el código");
principal.addComponent(campoTexto);

// Deje que el componente de error sea limpio inicialmente .
campoTexto.setComponentError(null); // (realmente el valor predeterminado)

// Tener un botón a la derecha del campo (y alinearlo apropiadamente).
final Button boton = new Button("Aceptar!");
principal.addComponent(boton);
((VerticalLayout)principal.getContent())
        .setComponentAlignment(boton, Alignment.BOTTOM_LEFT);

// Controlar los clics del botón
boton.addListener(new Button.ClickListener() {
    public void botonClick(ClickEvent event) {
        // Si el valor del campo es incorrecto, establecer su error.
        // (Permitir sólo caracteres alfanuméricos.)
        if (! ((String) campoTexto.getValue()).matches("^\\w*$")) {
            // Colocar el componente en estado de error y
            // establecer el mensaje de error.
            campoTexto.setComponentError(
                new UserError("Debe ser letras y números"));
        } else {
            // De lo contrario, limpiarlo.
            campoTexto.setComponentError(null);
        }
    }
});

Figura 4.7. Indicador de error activo

El componente Form controla y muestra también los errores de los campos contenidos de modo que se muestra tanto el indicador de error como el mensaje en un área especial del indicador de error. Consulte la Sección 5.19, "Form" y la Sección 5.19.3, "Validar la Entrada del Formulario" para obtener detalles sobre el componente Form y la validación de la entrada del formulario.

4.7.2 Notificaciones

Las notificaciones son errores o cajas de información que aparecen normalmente en el centro de la pantalla. Un cuadro de notificación tiene un título y una descripción opcional e icono. La caja se queda en la pantalla durante un tiempo determinado o hasta que el usuario haga clic en él. El tipo de notificación define la apariencia y el comportamiento predeterminado de una notificación.

Las notificaciones están siempre asociadas con un objeto window, que puede ser una ventana secundaria (la posición siempre es con relación a la vista completa del navegador). La clase Window proporciona un método showNotification() para mostrar las notificaciones. El método lleva como parámetros un título y una descripción opcional y el tipo de notificación. El método también acepta un objeto de la notificación del tipo Window.Notification, como se describe más adelante.

ventanaPrincipal.showNotification("Este es el título",
                            "Esta es la descripción");

Figura 4.8. Notificacion

El título y la descripción son, por defecto, escritos en la misma línea. Si desea tener un salto de línea entre ellos, utilice el marcado XHTML de salto de línea de "<br/>". Puede utilizar cualquier código XHTML en el título y la descripción de una notificación. Si es posible obtener el contenido de la notificación desde la entrada del usuario, debería sanear cuidadosamente el contenido, como se señala en la Sección 12.9.1, "Sanear la Entrada del Usuario para Prevenir Agujeros de Seguridad".

principal.showNotification("Esta es una advertencia",
            "<br/>Esta es la <i>última</i> advertencia",
            Window.Notification.TYPE_WARNING_MESSAGE);

Figura 4.9. Notificacion con Formato

El tipo de notificación define el estilo predeterminado y comportamiento global de una notificación. Si no hay ningún tipo de notificación el tipo utilizado es, "humanized" como valor predeterminado. Los tipos de notificación, se enumeran a continuación, son definidos en la clase Window.Notification.

TYPE_HUMANIZED_MESSAGE

Un mensaje fácil de utilizar que no molesta demasiado: no requiere confirmación haciendo clic y desaparece rápidamente. Se centra y tiene un color gris neutro.

TYPE_WARNING_MESSAGE

Las advertencias son mensajes de mediana importancia. Son mostradas con colores que no son ni neutrales ni tampoco distraen. Una advertencia es mostrada durante 1.5 segundos, pero el usuario puede hacer clic en el cuadro del mensaje para desestimarla. El usuario puede seguir interactuando con la aplicación, mientras que se muestra la advertencia.

TYPE_ERROR_MESSAGE

Los mensajes de error son notificaciones que requieren una mayor atención por parte del usuario, con colores de alerta y requieren que el usuario haga clic en el mensaje para descartarlo. El cuadro de mensaje de error no incluye una instrucción para hacer clic en el mensaje, aunque el cuadro de cierre en la esquina superior derecha lo indica visualmente. A diferencia de las otras notificaciones, el usuario no puede interactuar con la aplicación, mientras que es mostrado el mensaje de error.

TYPE_TRAY_NOTIFICATION

Las notificaciones de bandeja son mostradas en el área de la "bandeja del sistema", es decir, en la esquina inferior derecha de la vista del navegador. Como no suelen ocultar ninguna interfaz de usuario, se muestra por más tiempo que los mensajes tipo humanized o warning, por defecto 3 segundos. El usuario puede seguir interactuando con la aplicación normalmente mientras se muestra la bandeja de notificación.

Todas las características específicas de los tipos de notificaciones pueden ser controladas con los atributos de Window.Notification. Puede pasar explícitamente un objeto de notificación creado al método showNotification().

// Crear una notificación con la configuración por defecto para una advertencia.
Window.Notification notif = new Window.Notification(
        "Tenga cuidado!!",
        "Este mensaje se esconde en la esquina superior izquierda!",
        Window.Notification.TYPE_WARNING_MESSAGE);
 
// Establecer la posición.
notif.setPosition(Window.Notification.POSITION_TOP_LEFT);
 
// Que se quede allí hasta que el usuario haga clic en él
notif.setDelayMsec(-1);
 
// Mostrar en la ventana principal.
principal.showNotification(notif);

El método setPosition() permite establecer la posición de la notificación. El método toma como parámetro cualquiera de las constantes:

Window.Notification.POSITION_CENTERED
Window.Notification.POSITION_CENTERED_TOP
Window.Notification.POSITION_CENTERED_BOTTOM
Window.Notification.POSITION_TOP_LEFT
Window.Notification.POSITION_TOP_RIGHT
Window.Notification.POSITION_BOTTOM_LEFT
Window.Notification.POSITION_BOTTOM_RIGHT


El método setDelayMSec() le permite establecer el tiempo en milisegundos durante cuánto tiempo se muestra la notificación. El valor del parámetro -1 significa que el mensaje se muestra hasta que el usuario haga clic en el cuadro de mensaje. Esto también impide la interacción con otras partes de la ventana de la aplicación, como es el comportamiento predeterminado de los mensajes de error. Sin embargo, esto no, agrega el cuadro de cierre que tiene la notificación de error.

4.7.3 Personalizar los Mensajes del Sistema

Los mensajes del sistema son notificaciones que indican un estado importante no válido en una aplicación que por lo general requiere reiniciar la aplicación. El tiempo de espera de una sesión es tal vez el ejemplo más típico de estado.

Los mensajes del sistema son cadenas administradas en la clase SystemMessages.
  • sessionExpired
    La sesión del servlet Application ha expirado. Una sesión expira si no se hacen solicitudes al servidor durante el intervalo de tiempo de espera de la sesión. El intervalo de tiempo de espera de la sesión puede ser configurado con el parámetro session-timeout en web.xml, como se describe en la Sección 4.8.3, "El Descriptor de Despliegue web.xml".

    communicationErrorURL
    Un problema de comunicación no especificado entre el Motor del Lado del Cliente Vaadin y el servidor de aplicaciones. El servidor puede estar no disponible o hay algún otro problema.

    authenticationError
    Este error se produce si es recibida una respuesta 401 (No autorizado) a una petición desde el servidor.

    internalError
    Un problema interno serio, posiblemente indicando un error de programación en el Motor de Lado del Cliente Vaadin o en algún código personalizado del lado del cliente.

    outOfSync
    El estado del lado del cliente no es válido con respecto al estado del lado del servidor.

    cookiesDisabled
    Informa al usuario que las cookies están desactivadas en el navegador y la aplicación no funciona sin ellas.

Cada mensaje tiene cuatro propiedades: un título corto, el mensaje actual, una dirección URL para redireccionar después de mostrar el mensaje, y la propiedad que indica si la notificación está activada.

Los detalles adicionales pueden ser escritos (en Inglés) en la ventana de la consola de depuración descrito en la Sección 12.4, "Modo de Depuracion y Producción".

Puede sobrescribir los mensajes predeterminados del sistema implementando el método getSystemMessages() en la clase application. El método debe devolver un Application.SystemMessages. La manera más fácil de personalizar los mensajes es utilizar un objeto CustomizedSystemMessages de la siguiente manera:

// Sobreescribe la implementación predeterminada
public static SystemMessages getSystemMessages() {
    CustomizedSystemMessages mensajes =
            new CustomizedSystemMessages();
    mensajes.setSessionExpiredCaption("Ohno, la sesión ha finalizado!");
    mensajes.setSessionExpiredMessage("No funciona en reposo!");
    mensajes.setSessionExpiredNotificationEnabled(true);
    mensajes.setSessionExpiredURL("http://vaadin.com/");
    return mensajes;
}

Observe que el método especial getSystemMessages() no está definido en una interfaz, tampoco existe en la superclase Application.

4.7.4 Controlar Excepciones No Detectadas

El desarrollo de aplicaciones con Vaadin sigue el modelo de programación orientada a eventos. Los eventos del ratón y teclado causan en el cliente (por lo general de más alto nivel) eventos del lado del servidor, que pueden ser controlados con oyentes, y así es como funciona la mayor parte de la lógica de la aplicación. Controlar los eventos puede dar lugar a excepciones ya sea en la lógica de la aplicación o en el mismo framework, pero algunos de ellos no pueden ser capturados correctamente.

Por ejemplo, en el siguiente fragmento de código, lanzamos un error en un oyente de eventos, pero este no lo captura, por lo que el framework se cae.

final Button boton = new Button ("Fállame");

boton.addListener(new Button.ClickListener() {
    public void botonClick(ClickEvent event) {
        // Lanzar alguna excepción.
        throw new RuntimeException("Usted no puede atrapar esto.");
    }
});

Cualquier excepción que se produzcan en la cadena de llamada, pero que no es capturada en ningún otro nivel, son finalmente capturadas por el adaptador de terminal en ApplicationServlet, el componente de más bajo nivel que recibe las peticiones del cliente. El adaptador de terminal pasa todas las excepciones como eventos al oyente de error de la instancia Application a través de la interfaz Terminal.ErrorListener. La clase Application por defecto, no lanza, reenvió de excepciones.

La razón de esta lógica de control de errores se encuentra en la lógica que controla la sincronización del estado del componente entre el cliente y el servidor. Queremos controlar todos los cambios variables serializados en la petición del cliente, porque de lo contrario el estado de los componentes del lado del cliente y del lado del servidor se des sincronizarian con mucha facilidad, lo que podría poner toda la aplicación en un estado inválido.

La implementación predeterminada de la interfaz Terminal.ErrorListener en la clase Application simplemente imprime el error en la consola. Este también intenta encontrar un componente relacionado con el error. Si la excepción se produjo en un oyente vinculado a un componente, el componente es considerado como el componente relacionado a la excepción. Si es encontrado un componente relacionado, el controlador de errores establece el error del componente para él, puede establecer el mismo atributo con setComponentError().

En la interfaz de usuario, el error del componente es mostrado con un pequeño signo "!" de color rojo (en el tema por defecto). Si mueve el puntero del ratón sobre él, podrá ver el seguimiento inverso entero de la excepción en un gran cuadro de descripción, como se ilustra en la Figura 4.10, "Excepción No Detectada en el Indicador de Error del Componente" para el anterior código de ejemplo.

Figura 4.10. Excepción No Detectada en el Indicador de Error del Componente

Puede cambiar fácilmente la lógica para controlar los errores terminales sobrescribiendo el método terminalError() en su clase de aplicación (la que hereda Application) o estableciendo un oyente de error personalizado con el método setErrorHandler. Puede descartar con seguridad el control por defecto o ampliar su uso con su control de error personalizado o sistema de registro. En el siguiente código de ejemplo, las excepciones también son reportadas como notificaciones en la ventana principal.

@Override
public void terminalError(Terminal.ErrorEvent event) {
    // Llamar a la implementación por defecto.
    super.terminalError(event);

    // Algún comportamiento personalizado.
    if (getMainWindow() != null) {
        getMainWindow().showNotification(
                "Se produjo una excepción sin control!",
                event.getThrowable().toString(),
                Notification.TYPE_ERROR_MESSAGE);
    }
}

El control de otras excepciones funcionan del modo habitual para los Servlets Java. Las excepciones no detectadas son finalmente detectadas y controladas por el servidor de aplicaciones.



Anterior
4.6. Apagar una Aplicación
Siguiente
4.8. Configurar el Entorno de la Aplicación

No hay comentarios.:

Publicar un comentario