En este tema, aprenderemos cómo manejar errores en TypeScript, especialmente en el contexto de la programación asíncrona. El manejo adecuado de errores es crucial para crear aplicaciones robustas y confiables. Veremos cómo utilizar try...catch, cómo manejar errores en promesas y funciones async/await, y algunos patrones avanzados para el manejo de errores.

Contenido

Introducción al Manejo de Errores

El manejo de errores es el proceso de anticipar, detectar y responder a las condiciones de error en un programa. En TypeScript, al igual que en JavaScript, podemos manejar errores utilizando try...catch, promesas y async/await.

Manejo de Errores con try...catch

El bloque try...catch es una estructura básica para manejar errores en JavaScript y TypeScript. Permite capturar excepciones que ocurren en el bloque try y manejarlas en el bloque catch.

Ejemplo:

function divide(a: number, b: number): number {
    if (b === 0) {
        throw new Error("No se puede dividir por cero");
    }
    return a / b;
}

try {
    const result = divide(10, 0);
    console.log(result);
} catch (error) {
    console.error("Error:", error.message);
}

Explicación:

  • La función divide lanza un error si el divisor es cero.
  • El bloque try intenta ejecutar la función divide.
  • Si ocurre un error, el bloque catch captura el error y lo maneja, imprimiendo un mensaje en la consola.

Manejo de Errores en Promesas

Las promesas en JavaScript y TypeScript tienen un método catch que se utiliza para manejar errores.

Ejemplo:

function fetchData(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (url === "bad_url") {
                reject(new Error("URL no válida"));
            } else {
                resolve("Datos recibidos");
            }
        }, 1000);
    });
}

fetchData("bad_url")
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("Error:", error.message);
    });

Explicación:

  • La función fetchData simula una llamada a una API que puede fallar.
  • Si la URL es "bad_url", la promesa se rechaza con un error.
  • El método catch se utiliza para manejar el error.

Manejo de Errores con async/await

El uso de async/await simplifica el manejo de promesas y permite utilizar try...catch para manejar errores.

Ejemplo:

async function fetchDataAsync(url: string): Promise<string> {
    if (url === "bad_url") {
        throw new Error("URL no válida");
    }
    return "Datos recibidos";
}

async function main() {
    try {
        const data = await fetchDataAsync("bad_url");
        console.log(data);
    } catch (error) {
        console.error("Error:", error.message);
    }
}

main();

Explicación:

  • La función fetchDataAsync lanza un error si la URL es "bad_url".
  • La función main utiliza await para esperar el resultado de fetchDataAsync.
  • El bloque try...catch maneja cualquier error que ocurra durante la llamada a fetchDataAsync.

Patrones Avanzados de Manejo de Errores

Retorno de Errores en Lugar de Lanzarlos

En algunos casos, puede ser útil retornar errores en lugar de lanzarlos, especialmente en funciones que se llaman frecuentemente.

Ejemplo:

type Result<T> = { success: true, data: T } | { success: false, error: Error };

function divideSafe(a: number, b: number): Result<number> {
    if (b === 0) {
        return { success: false, error: new Error("No se puede dividir por cero") };
    }
    return { success: true, data: a / b };
}

const result = divideSafe(10, 0);
if (result.success) {
    console.log("Resultado:", result.data);
} else {
    console.error("Error:", result.error.message);
}

Explicación:

  • La función divideSafe retorna un objeto que indica si la operación fue exitosa o no.
  • Esto permite manejar errores sin utilizar try...catch.

Ejercicios Prácticos

Ejercicio 1: Manejo de Errores con try...catch

Escribe una función readFile que simule la lectura de un archivo. Si el nombre del archivo es "not_found.txt", la función debe lanzar un error. Utiliza try...catch para manejar el error.

function readFile(fileName: string): string {
    if (fileName === "not_found.txt") {
        throw new Error("Archivo no encontrado");
    }
    return "Contenido del archivo";
}

try {
    const content = readFile("not_found.txt");
    console.log(content);
} catch (error) {
    console.error("Error:", error.message);
}

Ejercicio 2: Manejo de Errores en Promesas

Escribe una función fetchUserData que simule una llamada a una API para obtener datos de usuario. Si el ID del usuario es 0, la promesa debe ser rechazada con un error. Utiliza el método catch para manejar el error.

function fetchUserData(userId: number): Promise<string> {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId === 0) {
                reject(new Error("ID de usuario no válido"));
            } else {
                resolve("Datos del usuario");
            }
        }, 1000);
    });
}

fetchUserData(0)
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("Error:", error.message);
    });

Ejercicio 3: Manejo de Errores con async/await

Escribe una función fetchProductData que simule una llamada a una API para obtener datos de un producto. Si el ID del producto es 0, la función debe lanzar un error. Utiliza async/await y try...catch para manejar el error.

async function fetchProductData(productId: number): Promise<string> {
    if (productId === 0) {
        throw new Error("ID de producto no válido");
    }
    return "Datos del producto";
}

async function main() {
    try {
        const data = await fetchProductData(0);
        console.log(data);
    } catch (error) {
        console.error("Error:", error.message);
    }
}

main();

Conclusión

En esta sección, hemos aprendido cómo manejar errores en TypeScript utilizando try...catch, promesas y async/await. También hemos explorado algunos patrones avanzados para el manejo de errores. El manejo adecuado de errores es esencial para crear aplicaciones robustas y confiables. En la siguiente sección, profundizaremos en patrones asíncronos avanzados para mejorar aún más nuestras habilidades en la programación asíncrona.

© Copyright 2024. Todos los derechos reservados