Podręcznik dla początkujących dotyczący obsługi błędów w TypeScript

Skuteczna obsługa błędów jest kluczowa w każdym języku programowania, a TypeScript nie jest wyjątkiem. Prawidłowa obsługa błędów pomaga w tworzeniu solidnych i niezawodnych aplikacji poprzez umiejętne zarządzanie nieoczekiwanymi warunkami. Ten przewodnik obejmuje podstawy obsługi błędów w TypeScript i zawiera praktyczne przykłady dla początkujących.

Zrozumienie błędów w TypeScript

Błędy w TypeScript, podobnie jak w JavaScript, występują w czasie wykonywania lub kompilacji. TypeScript zapewnia bezpieczeństwo typu, które może wychwycić wiele potencjalnych problemów w czasie kompilacji, ale błędy w czasie wykonywania nadal muszą być odpowiednio zarządzane.

Podstawowa obsługa błędów za pomocą try i catch

W TypeScript błędy czasu wykonania obsługujesz za pomocą bloków try i catch. To podejście pozwala na wykonanie kodu, który może spowodować błąd, i obsługę tego błędu, jeśli wystąpi.

Przykład try i catch

function divide(a: number, b: number): number {
  try {
    if (b === 0) {
      throw new Error("Cannot divide by zero");
    }
    return a / b;
  } catch (error) {
    console.error(error.message);
    return NaN; // Return NaN to indicate an error
  }
}

console.log(divide(10, 2)); // Output: 5
console.log(divide(10, 0)); // Output: Cannot divide by zero

W tym przykładzie funkcja divide próbuje podzielić dwie liczby. Jeśli dzielnik jest zerem, zgłaszany jest błąd, który jest wychwytywany przez blok catch, który rejestruje komunikat o błędzie.

Niestandardowe typy błędów

TypeScript umożliwia zdefiniowanie niestandardowych typów błędów, aby lepiej reprezentować określone warunki błędów. Niestandardowe typy błędów pomagają w kategoryzowaniu błędów i skuteczniejszej obsłudze.

Tworzenie niestandardowego typu błędu

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

function divide(a: number, b: number): number {
  try {
    if (b === 0) {
      throw new DivisionError("Cannot divide by zero");
    }
    return a / b;
  } catch (error) {
    if (error instanceof DivisionError) {
      console.error(`Custom Error: ${error.message}`);
    } else {
      console.error("An unexpected error occurred");
    }
    return NaN; // Return NaN to indicate an error
  }
}

console.log(divide(10, 2)); // Output: 5
console.log(divide(10, 0)); // Output: Custom Error: Cannot divide by zero

Tutaj definiujemy niestandardową klasę błędu DivisionError, która rozszerza wbudowaną klasę Error. Używamy tego niestandardowego błędu w funkcji divide, aby zapewnić bardziej szczegółową obsługę błędów.

Ochrona typu za pomocą instanceof

Zabezpieczenia typu, takie jak instanceof, pomagają zawęzić typ obiektu błędu w bloku catch, co umożliwia obsługę różnych typów błędów w różny sposób.

Przykład ochrony typu

function processInput(input: string | number) {
  try {
    if (typeof input === "string") {
      console.log(input.toUpperCase());
    } else {
      throw new Error("Input must be a string");
    }
  } catch (error) {
    if (error instanceof Error) {
      console.error(`Error: ${error.message}`);
    } else {
      console.error("An unknown error occurred");
    }
  }
}

processInput("hello"); // Output: HELLO
processInput(42); // Output: Error: Input must be a string

W tym przykładzie zaprezentowano ochronę typu w bloku catch, która zapewnia, że ​​obiekt błędu jest instancją Error, co pozwala na dokładną obsługę błędów.

Używanie finally do czyszczenia

Blok finally może być używany do wykonywania kodu, który powinien zostać uruchomiony niezależnie od tego, czy wystąpił błąd, czy nie. Jest to przydatne w przypadku operacji czyszczenia, takich jak zamykanie plików lub zwalnianie zasobów.

Przykład z finally

function readFile(filePath: string): string {
  try {
    // Simulate reading a file
    if (filePath === "") {
      throw new Error("File path cannot be empty");
    }
    return "File content";
  } catch (error) {
    console.error(`Error: ${error.message}`);
    return "";
  } finally {
    console.log("Cleanup: Closing file");
  }
}

console.log(readFile("path/to/file")); // Output: File content
console.log(readFile("")); // Output: Error: File path cannot be empty
                            //         Cleanup: Closing file

W tym przykładzie blok finally zapewnia, że ​​komunikat czyszczący zostanie zarejestrowany niezależnie od tego, czy wystąpi błąd.

Wniosek

Efektywne zarządzanie błędami jest kluczowe dla tworzenia niezawodnych aplikacji TypeScript. Używając try i catch, niestandardowych typów błędów, ochrony typów i finally, możesz zarządzać błędami bardziej efektywnie i upewnić się, że Twoja aplikacja zachowuje się przewidywalnie nawet w obliczu nieoczekiwanych warunków.

Dzięki tym technikom możesz obsługiwać błędy z wdziękiem i zwiększać solidność swojego kodu TypeScript. Ćwicz te koncepcje, aby stać się biegłym w obsłudze błędów TypeScript i pisać bardziej odporne aplikacje.