Anuncios

Bienvenidos sean a este post, hoy veremos un tema peliagudo.

Anuncios

Hasta los posts anteriores, hemos visto como se envia la informacion mediante distintos metodos, asi como algunos temas que debemos considerar para no omitir informacion y como trabaja en conjuncion con la parte asincronica pero que sucede cuando ocurra un error? Tambien poseemos un mecanismo para poder capturarlos y manejar cuando surjan. Analicemos el siguiente codigo:

import {Observable, of} from 'rxjs';
import {map} from 'rxjs/operators';

interface IValor {
        valor: number;
}
interface IObjeto {
        id?: IValor;
}

const objEmisor: Observable<IObjeto> = of(
        { id: { valor: 1 } },
        {},
        { id: { valor: 2 } }
);

const valorId = objEmisor.pipe(
        map((valor: IObjeto) => {
                return valor.id!.valor;
        })
);

valorId.subscribe((valor: number) => {
        console.log('Recibido: ' + valor);
});
Anuncios
Anuncios

Primero importaremos el tipo para estos datos, Observable, y luego las distintas funciones que usaremos. Lo siguiente sera definir dos interfaces, la primera es para un valor y la segunda sera para el id o propiedad de un objeto, como tipo usara al de la interfaz anterior y este a su vez sera opcional. Luego crearemos nuestro emisor y para ello usamos a of donde pasaremos tres objetos, dos con informacion y uno vacio. En este caso el Observable sera del tipo de la segunda interfaz. Lo siguiente sera una constante que almacenara el resultado devuelto por pipe y en esta usaremos a map para recibir el valor de of y aqui devolveremos el contenido de valor dentro de id pero con una particularidad. En este caso usamos al operador de asignnacion definitiva y por lo tanto este dato no puede ser undefined o unknown. Finalmente tenemos el subscribe para recibir el valor enviado por map y lo mostraremos en la consola. Compilemos y veamos como es su salida:

tinchicus@dbn001vrt:~/lenguajes/ts/31$ node mirar.js
Recibido: 1
/home/tinchicus/node_modules/rxjs/dist/cjs/internal/util/reportUnhandledError.js:13
            throw err;
            ^

TypeError: Cannot read properties of undefined (reading 'valor')
    at /home/tinchicus/lenguajes/ts/31/mirar.js:7:21
    at /home/tinchicus/node_modules/rxjs/dis.... muchas mas informacion
Anuncios

Si se dieron cuenta nos compilo sin ningun error pero al momento de ejecutarlo nos devolvio un error. Si bien proceso correctamente el primer valor cuando paso al vacio nos devolvio un error y esta descripcion:

TypeError: Cannot read properties of undefined (reading 'valor')
Anuncios

Vamos a tomar del codigo anterior el bloque correspondiente al subscribe y hagamos la siguiente modificacion:

valorId.subscribe(
        (valor: number | null) => {
                console.log('Recibido: ' + valor);
        },
        (error: unknown) => {
                console.log('error: ' + error);
        },
        () => {
                console.log('completo');
        }
);
Anuncios

En este caso en lugar de tener una funcion tendremos tres para distintas situaciones. La primera es la que deberia recibir todos los datos y procesarlos. La segunda es para el caso que el dato sea desconocido y en este caso envia el error a la consola y el ultimo para cuando se haya enviado todo e indique su finalizacion. Si lo compilamos y ejecutamos nuevamente, tendremos esta salida:

$ node mirar.js
Recibido: 1
error: TypeError: Cannot read properties of undefined (reading 'valor')
$
Anuncios

Nuevamente tenemos un error al procesar al segundo dato. Pero si lo comparan con la salida anterior tenemos una version mas limpia aunque seguimos sin completar la funcion en si porque tenemos un dato mas.

Anuncios

Pero disponemos de una herramienta para poder trabajar con nuestros errores y esta se encuentra entre los operadores, para ello debemos tomar nuestro codigo y realizar las siguientes modificaciones:

import {Observable, of} from 'rxjs';
import {map, catchError} from 'rxjs/operators';

interface IValor {
        valor: number;
}
interface IObjeto {
        id?: IValor;
}

const objEmisor: Observable<IObjeto> = of(
        { id: { valor: 1 } },
        {},
        { id: { valor: 2 } }
);

const valorId = objEmisor.pipe(
        map((valor: IObjeto) => {
                return valor.id!.valor;
        }),
        catchError((error: unknown) => {
                console.log('se capturo: ' + error);
                return of(null);
        })
);

valorId.subscribe(
        (valor: number | null) => {
                console.log('Recibido: ' + valor);
        },
        (error: unknown) => {
                console.log('error: ' + error);
        },
        () => {
                console.log('completo');
        }
);
Anuncios

La primera modificacion es en la importacion de la funcion catchError en los modulos de operadores. Con esto ya tenemos habilitado nuestro capturador de errores. La siguiente modificacion es en objEmisor. En map agregaremos el operador catchError y en este le pasaremos un argumento de tipo unknown, por lo tanto cuando tengamos esta situacion nos mostrara el mensaje en consola adjunto con el de error. Luego procedemos a enviar un null mediante of. Por que hacemos esto? de eso hablaremos en un momento. El resto no recibio ninguna modificacion. Compilemos y veamos como es su salida:

$ node mirar.js
Recibido: 1
se capturo: TypeError: Cannot read properties of undefined (reading 'valor')
Recibido: null
completo
$
Anuncios
Anuncios

Como podemos ver ahora si se completo el codigo pero ocurrieron dos cosas. Primero no tenemos el valor 2 del segundo id. Por otro lado ahora tenemos un null en su lugar. Esto es debido a que al momento de emitir cuando ocurre un error siempre se interrumpe la emision. Por esta razon para poder continuar debemos realizar otra emision, en este caso le enviamos un null porque sabemos que es un tipo aceptado en subscribe, por lo tanto ahora puede procesarlo y como es el ultimo dato que emitimos, subscribe procede a notificarnos con el completo para saber que se llego al final.

Anuncios

Esta es una herramienta similar a try/catch de otros lenguajes donde si ocurre alguna eventualidad el catch se encargara de manejar al error/excepcion por nosotros.

Anuncios

En resumen, hoy hemos visto como manejar errores, primero una forma practica pero que interrumpira nuestra emision, la segunda es la opcion correcta que incluso nos permite continuar con nuestro codigo. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50