4,7. Manejo de errores


4,7. Manejo de errores


4.7.1. Indicador de error y mensaje

Todas la piezas tienen un error indicador construido dentro que se puede configurar usando “setComponentError() - colocaPiezaError()” o puede ser activado si no se puediera validar la pieza. Como con los “titulos de pieza”, el lugar del indicador es manejado a través del disenyo donde se contiene la pieza. Normalmente el indicador de error es colocado a la derecha del texto del Titulo. Colocando el mouse encima del cuadro muestra el mensaje del error.

El siguiente ejemplo ensenya como puedes colocar el error de la pieza. El ejemplo en principio solo valida el cuadro de valor sin usar el validador actual.


// Create a field.
final TextField textfield = new TextField("Enter code");
main.addComponent(textfield);

// Let the component error be initially clear.
textfield.setComponentError(null); // (actually the default)

// Have a button right of the field (and align it properly).
final Button button = new Button("Ok!");
main.addComponent(button);
((VerticalLayout)main.getLayout())
        .setComponentAlignment(button, Alignment.BOTTOM_LEFT);

// Handle button clicks
button.addListener(new Button.ClickListener() {
    public void buttonClick(ClickEvent event) {
        // If the field value is bad, set its error.
        // (Allow only alphanumeric characters.)
        if (! ((String) textfield.getValue()).matches("^\\w*$")) {
            // Put the component in error state and
            // set the error message.
            textfield.setComponentError(
                new UserError("Must be letters and numbers"));
        } else {
            // Otherwise clear it.
            textfield.setComponentError(null);
        }
    }
});

// Crea un cuadro.
final TextoCuadro textocuadro = nuevo TextoCuadro("Introduce codigo");
principal.sumaPieza(cuadrotexto);

// Permite el error de la pieza inicialmente clara.
textocuadro.colocaPiezaError(nulo); // (Actualmente el Standard)

// Ten un boton a la derecha del cuadro (i alinealo adecuadamente)
final Boton boton = nuevo Boton("Ok"");
principal.sumaPieza(boton);
((VerticalDisenyo)principal.recibeDisenyo())
        .colocaPiezaAlineada(boton, Alineada.FONDO_IZQUIERDA);

// Maneja clicks del botón
boton.sumaEscuchador(nuevo Boton.ClickEscuchador() {
    collectivo vacio botonClick(ClickSucesso sucesso) {
        // Si el valor del cuadro es malo, coloca que es un error.
        // (Permite solo caracteres alphanumericos)
        si (! ((Cadena) cuadrotexto.recibeValor()).esigual("^\\w*$")) {
            // Pon la pieza en estado de error y
            // coloca el mensaje de error.
            cuadrotexto.colocaPiezaError(
                nuevo UsuarioError("Tienen que ser letras y numeros"));
        } otracosa {
            // En otro caso limpialo
            cuadrotexto.colocaPiezaError(nulo);
        }
    }
});

Figure 4.6. Indicador de error activo

La pieza formulario maneja y muestra tambien los errores de los cuadros contenidos, mostrando los dos el indicador de error y el mensaje en una especial area indicadora de error. Ver tambien "Capitulo 5.19 - “formularios” y el Capitulo 5.19.3 “Validando introductores de formulario” para mas detalles sobre la pieza formulario i la validacion del introductor de formulario.

4.7.2. Notificadiones.

Las notificaciones son errores o cajas de informacion que aparecen normalmente al centro de la pantalla. Una caja de notificacion suele tener un titulo una descripcion opcional i un icono. La caja se queda en la pantalla durante un tiempo programado o hasta que el usuario lo clicke. El tipo de notificacion explica que standard de apariencia y importancia de la notificacion.

Las notificaciones son siempre associadas con un objeto ventana, que puede ser una ventana hija (el posicionamiento es siempre relativo a la tematica del navegador). La classe ventana suministra un codigo “showNotification() - ensenyaNotificaciones()” para mostrar notificaciones. El codigo coje el titulo y una descripcion opcional y tipos de notificaciones como codigos. el codigo tambien acepta notificaciones objeto del tipo “Window.Notification - VentanaNotificacion” como describiremos mas adelante.


mainwindow.showNotification("This is the caption",
                            "This is the description");

principalventana.ensenyaNotificaciones("Este es el titulo",
                            "Esta es la descripcion");

Figure 4.7. Notificaciones

El titulo i la descripcion son, por Standard, escritos en la misma linea. Si quieres tener una linea rota entre ellos, usa el rompedor de lineas XHTML “
”. Puedes usar cualquier “markup” XHTML" en el titulo y en la descripcion de la notificacion. Si és possible de recibir el contenido de la notificacion del introductor del usuario, deverias limpiar el contenido con delicadeza, como explica en el Capitulo 12.9.1 “Limpiando el introductor del usuario para prevenir cruzes-paginas scripting”.


main.showNotification("This is a warning",
            "<br/>This is the <i>last</i> warning",
            Window.Notification.TYPE_WARNING_MESSAGE);

principal.muestraNotificaciones("Esto es una advertencia",
            "<br/>Esto es la <i>ultima</i> advertencia",
            Ventana.Notificacion.TIPO_ADVERTENCIA_MENSAGE);

Figure 4.8. Notificación con formato

Los tipos de notificaciones usan el disenyo standard y comportamiento de una notificacion. Si no se programa un tipo, se le de el “humano” tipo que se usa Standard. Los tipos de notificaciones, que se muestran a continuacion, son definidas en la classe “Window.Notification - Ventana.Notificaciones”.

“TYPE_HUMANIZED_MESSAGE - TIPO_HUMANIZADO_MENSAJE”

És un mensaje amistoso que no advierte demasiado: no requiere una comfirmacion por click, y desaparece rapidamente. Esta centrado y tiene un color neutral gris.

TYPE_WARNING_MESSAGE - TIPO_ADVERTENCIA_MENSAJE

Las advertencias son mensajes de media importancia. Son mostradas con colores que no son tan neutrales i que atraen algo de atencion. Un mensaje de advertencia es mostrado durante 1.5segundo, Y el usuario puede cerrar el cuadro para cerrarlo. El usuario puede seguir interactuando con la App aunque aparezca esta notificacion.

“TYPE_ERROR_MESSAGE - TIPO_ERROR_MENSAJE”

Los mensajes errore son notificaciones que requieren la atencion maxima del usuario, con colores alartante y requiriendo al usuario clicar el mensaje para cerrarlo. Este error caja mensaje no incluye una instruccion de clicar el mensaje, hay un cerrarboton en la parte de arriba a la derecha esquina que lo indica visualmente. A diferencia de otras notificacione, el usuario no puede Interaccionar con la App mientras el mensaje de error sea mostrado.

“TYPE_TRAY_NOTIFICATION - TIPO_BANDEJA_NOTIFICACION”

Las notificaciones del tipo bandeja son mostradas en el area del “sistema bandeja”, que ésta en la esquina inferior derecha de la vista del navegador. Como no suelen impedir cualquier interaccion del usuario, se muestran durante mas tiempo que el tipo HUMANIZED o mensajes ADVERTENCIA, 3 segundos en Standard. El usuario puede seguir interactuando con la applicación normalmente mientras la notificacion bandeja sea visible.

Todas las herramientas de un tipo de notificacion pueden ser controladas con los rasgos de “Window.Notification - Ventana.Notificaciones”. Puedes pasar un objeto de notificacion creato con el codigo “showNotificacion() - muestraNotificación”.


// Create a notification with default settings for a warning.
Window.Notification notif = new Window.Notification(
        "Be warned!",
        "This message lurks in the top-left corner!",
        Window.Notification.TYPE_WARNING_MESSAGE);
 
// Set the position.
notif.setPosition(Window.Notification.POSITION_TOP_LEFT);
 
// Let it stay there until the user clicks it
notif.setDelayMsec(-1);
 
// Show it in the main window.
main.showNotification(notif);

// Crea una notificacion con programacion standart para advertencia
Ventana.Notificacion notif = nueva Ventana.Notificacion(
        "Estate advertido!",
        "Este mensaje esta en el top-izquierda esquina",
        Ventana.Notificaciones.TIPO_ADVERTENCIA_MENSAJE);
 
// Coloca la posicion.
notif.colocaPosicion(Ventana.Notificacion.POSICION_TOP_IZQUIERDA);
 
// Digamos que se quede allí hasta que el usuario lo clike
notif.colocarEsperaMsec(-1);
 
// Muestralo en la ventana principal.
principal.muestraNotificacion(notif);

El codigo “setPosition() - colocaPosicion()” permite programar la posicion de la notificacion. El codigo coje como sus codigos cualquier de las persistentes:

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 “setDelayMSec() - colocaEsperaMSec()” te permite poner el tiempo en milisengundos por cuanto tiempo la notificacion sera mostrada. El valor -1 quiere decir que el mensaje sera mostrado hasta que el usuario clique la caja del mensaje. Tambien previene de interacciones con otras partes de la ventana App, como su comportamiento standard para mensajes de error. Lo que no hace, es sumar una caja de cerrar que la que ya tiene el notificador de error.
[b]

4.7.3. Personalizando mensajes del sistema
[/b]

Mensajes del sistema son notificaciones que indican un mayor estado invalido dentro una App que normalmente requiere resetear la App. La session timeout és quiza el mas typico como estado.

Mensajes del sistema son cadenas manejadas en la classe “SystemMessages - MensajesSystema”.

“sessionExpired - sessionCaducada”

El servlet de la App la session ha caducado. La session caduca si el server no recibe ninguna solicitud durante el tiempo de session timeout. La session timeout puede ser programada con el codigo “session-timeout - session-fueradetiempo” en el archibo web.xml, En el capitulo 4.8.3 “Desplegando el descriptor web.xml”. se descibe como funciona.

“communicationErrorURL - comunicacionErrorURL”

És una comunicacion desconocida entre Vaadin del motor del lado del cliente y la App del server. El server quizá no esta disponible o hay quiza otro tipo de problema.

“authenticationError - errordeIdentificacion”

Este error ocurre si la respuesta 401 (no identificado) a una solicitud és recivida desde el server.

“internalError - errorInterno”

Un problema interno serio, quiza indica que hay un bug en el motor del lado del cliente de Vaadin, o en algun codigo personalizado del lado del cliente.

“outOfSync - fueraDeConexion”

El estado del lado del cliente es invalido con respecto al estado del lado del server.

“cookiesDisabled - cookiesIndisponible”

Informa al usuario que los cookies estan desactivados en el navegador y la App no funciona sin ellos.

Cada mensaje tiene 4 propiedades: un titulo corto, el mensaje actua, una URL para rederaccionar despues de ensenyar el mensaje, una propiedad indicadon si la notificacion esta habilitada.

Mas detalles deberian ser escritos (en ingles) para la ventana consola debug descrito en el capitulo 12.4, “Modo de debuy i produccion”

Puedes sobremontar el sistema de mensajes standart usando la herramienta codigo “getSystemMessages() - recibeMensajesSystema()” en la classe App. El metodo deveria devolverte un objeto “Application.SystemMessages - App.MensajesSistema”. El camino mas facil para personaizar los mensajes es usar el objeto “CustomizedSystemMessages - PersonalizadoSystemaMensajes” como en el siguiente caso:


// Override the default implementation
public static SystemMessages getSystemMessages() {
    CustomizedSystemMessages messages =
            new CustomizedSystemMessages();
    messages.setSessionExpiredCaption("Ohno, session expired!");
    messages.setSessionExpiredMessage("Don't idle!");
    messages.setSessionExpiredNotificationEnabled(true);
    messages.setSessionExpiredURL("http://vaadin.com/");
    return messages;
}

// Sobremontar la herramienta Standard
collectivo estatico SistemaMensajes recibeSistemaMensajes() {
    PersonalizadoSistemaMensajes mensajes =
            nuevo PersonalizadoSistemaMensajes();
    mensajes.colocaSessionCaducadaTitulo("Oh no", la session ha sido expirada");
    mensajes.colocaSessionCaducadaMensaje("No hay reposo!");
    mensajes.colocaSessionCaducadaNotificacionDisponible(verdadero);
    mensajes.colocaSessionCaducadaURL("http://vaadin.com/");
    devuelve mensajes;
}

Date cuenta que el codigo especial “getSystemMessages() - recibeSistemaMensajes()” no esta definida en un cuadro de interacciones “nor does” no existe en la superclasse App.

4.7.4. Manejando excepciones no cogidas

La creacion de Apps con Vaadin sigue el modelo sucesso-conducido programado. Los sucessos con el Mouse i el teclado en el cliente causa (normalmente niveles-mas-altos) sucessos en el lado del server, que pueden ser manejados con escuchadores, i así es como la mayoria de metodos/logia de la App trabaja. Manejando sucessos puede resultar en algunas excepciones o en los metodos/logia de la App o en el cuadro de trabajo en sí, pero algunos de ellos quizá no seran cogidos como es devido.

Por ejemplo, en el siguiente codigo, tiramos un error a un sucesso escuchador pero no lo pilla, asi que acaba cayendo en el cuadro de trabajo.


final Button button = new Button ("Fail Me");

button.addListener(new Button.ClickListener() {
    public void buttonClick(ClickEvent event) {
        // Throw some exception.
        throw new RuntimeException("You can't catch this.");
    }
});

final Botón boton = nuevo Boton ("Pierde me");

boton.sumaEscuchador(nuevo Boton.ClickEscuchador() {
    collectivo vacio botonClick(ClickSucesso sucesso) {
        // Tira alguna excepcion.
        tira nuevo RuntimeExcepcion("No puedes cojer esto.");
    }
});

Cualquiera como excepciones que occuren en la cadena de llamado, pero que no son cojidos en cualquier otro nivel, son temporalmente cojidos por el Adaptador final en el “ApplicationServlet - Servlet App”, la pieza mas bajo-nivel que recibe solicitudes del cliente. El adaptador final passa todas las excepciones como sucessos hacia el escuchador de errore de la fotografia App a través del interaccionador “Terminal.ErrorListener - Final.ErrorEscuchador”. La classe App no lo hace, por standard, tira estas excepcionas adelante.

La razón en esta logica/metodo de manejo-errores esta en la logica/metodologia que maneja los estados sincronizados de las piezas entre el cliente i el server. Queremos manejar todos los canvios en los transformables en serie, porque sino el estado de las piezas del lado del cliente i el lado del server se puede dessincronizar muy facilmente, lo que podria poner la App en un estado invalido.

La herramienta standard del interaccionador “Terminal.ErrorListener - Final.ErrorEscuchador” en la classe App solo imprime el error a la consola. Tambien intenta encontrar la pieza que esta associada con el error. Si la excepcion ocurrer en un escuchador fusionado a una pieza, la pieza se considera somo la pieza relacionada con la excepcion. Si una pieza relacionada con la excepcion es endcontrada, ese error maneja packs de piezas error por él, el mismo rasgo que puedes colocar con colocaPiezaError().

En las “interacciones de los usuarios”, las piezas error son ensenyadas con un pequenyo rojo simbolo “!” (en la tematica standard). Si colocas el puntero del mouse encima, vas a ver todo la ingeneria inversa registrada de la excepcion en un cuadro largo de consejo, como se ilustra en la imagen 4.9 “Excepciones no cogidas en el indicador de piezas error” con el siguiente codigo de ejemplo:

Figure 4.9. Excepciones no cogidas en el indicador de piezas error

Puedes canviar la logica/metodologai del manejo los errores finales facilmente sobremontando el codigo “terminalError() - finalError()” en tu classe App (la que incluye la App) o programando un escuchador de errores personalizado con el codigo “setErrorHandler - colocaErrorManejador”. Puedes de un modo seguro descartar el manejo standard o expandir su uso dcon tu manejo de errores personalizado o sistema de login. En el codigo ejemplo de acontinuacion, las excepciones son registradas como notificaciones en la ventana principal.


@Override
public void terminalError(Terminal.ErrorEvent event) {
    // Call the default implementation.
    super.terminalError(event);

    // Some custom behaviour.
    if (getMainWindow() != null) {
        getMainWindow().showNotification(
                "An unchecked exception occured!",
                event.getThrowable().toString(),
                Notification.TYPE_ERROR_MESSAGE);
    }
}

@Sobremontar
collectivo vacio finalError(Final.ErrorSucesso sucesso) {
    // Llamar la herramienta standard
    super.finalError(sucesso);

    // Algunos comportamientos personalizados.
    si (recibePrincipalVentana() != nulo) {
        recibePrincipalVentana().muestraNotificacion(
                "Una excepcion no chekeada ha sido occurida!",
                sucesso.recibeTirable().haciaCadena(),
                Notificacion.TIPO_ERROR_MENSAJE);
    }
}

Manejar otras excepciones funciona en el camino usual para Servles Java. No-cojidas excepciones son finalmente cogidas i manejadas por el server App.