La gestió d'errors és una part fonamental de qualsevol aplicació robusta. En aquest tema, aprendrem com gestionar errors en TypeScript, especialment en el context de la programació asíncrona. Veurem com utilitzar try...catch, com manejar errors en promeses i async/await, i com crear errors personalitzats.

Continguts

Gestió d'Errors amb try...catch

El bloc try...catch és una estructura de control que permet capturar i gestionar errors que es produeixen durant l'execució del codi.

Exemple

function divide(a: number, b: number): number {
    if (b === 0) {
        throw new Error("No es pot dividir per zero");
    }
    return a / b;
}

try {
    const result = divide(10, 0);
    console.log(result);
} catch (error) {
    console.error("S'ha produït un error:", error.message);
}

Explicació

  • throw new Error("No es pot dividir per zero"): Llença un error si el divisor és zero.
  • try: Intenta executar el codi dins del bloc.
  • catch (error): Captura l'error si es produeix i executa el codi dins del bloc catch.

Gestió d'Errors en Promeses

Quan treballem amb promeses, podem gestionar errors utilitzant el mètode .catch.

Exemple

function fetchData(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (url === "https://api.example.com/data") {
                resolve("Dades obtingudes correctament");
            } else {
                reject(new Error("URL no vàlida"));
            }
        }, 1000);
    });
}

fetchData("https://api.invalid.com/data")
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("S'ha produït un error:", error.message);
    });

Explicació

  • reject(new Error("URL no vàlida")): Llença un error si la URL no és vàlida.
  • .catch(error => {...}): Captura l'error si es produeix i executa el codi dins del bloc catch.

Gestió d'Errors amb async/await

L'ús de async/await fa que el codi asíncron sembli sincrònic, i podem utilitzar try...catch per gestionar errors.

Exemple

async function fetchDataAsync(url: string): Promise<string> {
    if (url !== "https://api.example.com/data") {
        throw new Error("URL no vàlida");
    }
    return "Dades obtingudes correctament";
}

async function main() {
    try {
        const data = await fetchDataAsync("https://api.invalid.com/data");
        console.log(data);
    } catch (error) {
        console.error("S'ha produït un error:", error.message);
    }
}

main();

Explicació

  • throw new Error("URL no vàlida"): Llença un error si la URL no és vàlida.
  • await fetchDataAsync(...): Espera que la promesa es resolgui.
  • try...catch: Captura l'error si es produeix i executa el codi dins del bloc catch.

Errors Personalitzats

Podem crear errors personalitzats per proporcionar més informació sobre l'error.

Exemple

class InvalidURLError extends Error {
    constructor(message: string) {
        super(message);
        this.name = "InvalidURLError";
    }
}

function fetchDataWithCustomError(url: string): Promise<string> {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (url === "https://api.example.com/data") {
                resolve("Dades obtingudes correctament");
            } else {
                reject(new InvalidURLError("La URL proporcionada no és vàlida"));
            }
        }, 1000);
    });
}

fetchDataWithCustomError("https://api.invalid.com/data")
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        if (error instanceof InvalidURLError) {
            console.error("Error personalitzat:", error.message);
        } else {
            console.error("S'ha produït un error:", error.message);
        }
    });

Explicació

  • class InvalidURLError extends Error: Defineix una classe d'error personalitzada.
  • reject(new InvalidURLError(...)): Llença un error personalitzat si la URL no és vàlida.
  • if (error instanceof InvalidURLError): Comprova si l'error és una instància de InvalidURLError.

Exercicis Pràctics

Exercici 1

Escriu una funció readFileAsync que llegeixi un fitxer de manera asíncrona i gestioni els errors si el fitxer no existeix.

Solució

import { promises as fs } from 'fs';

async function readFileAsync(filePath: string): Promise<string> {
    try {
        const data = await fs.readFile(filePath, 'utf-8');
        return data;
    } catch (error) {
        throw new Error(`No s'ha pogut llegir el fitxer: ${error.message}`);
    }
}

async function main() {
    try {
        const content = await readFileAsync('path/to/file.txt');
        console.log(content);
    } catch (error) {
        console.error(error.message);
    }
}

main();

Exercici 2

Crea una classe d'error personalitzada FileNotFoundError i utilitza-la en la funció readFileAsync.

Solució

import { promises as fs } from 'fs';

class FileNotFoundError extends Error {
    constructor(message: string) {
        super(message);
        this.name = "FileNotFoundError";
    }
}

async function readFileAsync(filePath: string): Promise<string> {
    try {
        const data = await fs.readFile(filePath, 'utf-8');
        return data;
    } catch (error) {
        throw new FileNotFoundError(`No s'ha pogut trobar el fitxer: ${error.message}`);
    }
}

async function main() {
    try {
        const content = await readFileAsync('path/to/file.txt');
        console.log(content);
    } catch (error) {
        if (error instanceof FileNotFoundError) {
            console.error("Error personalitzat:", error.message);
        } else {
            console.error("S'ha produït un error:", error.message);
        }
    }
}

main();

Conclusió

En aquesta secció, hem après com gestionar errors en TypeScript utilitzant try...catch, promeses, async/await i errors personalitzats. La gestió adequada dels errors és crucial per crear aplicacions robustes i fiables. Practica aquests conceptes amb els exercicis proporcionats per reforçar el teu coneixement.

© Copyright 2024. Tots els drets reservats