Guia para iniciantes em tratamento de erros do TypeScript

O tratamento eficaz de erros é crucial em qualquer linguagem de programação, e o TypeScript não é exceção. O tratamento adequado de erros ajuda a criar aplicativos robustos e confiáveis ​​ao gerenciar condições inesperadas graciosamente. Este guia cobrirá os fundamentos do tratamento de erros no TypeScript e fornecerá exemplos práticos para iniciantes.

Compreendendo erros no TypeScript

Erros no TypeScript, assim como no JavaScript, ocorrem durante o tempo de execução ou de compilação. O TypeScript fornece segurança de tipo que pode capturar muitos problemas potenciais no tempo de compilação, mas erros de tempo de execução ainda precisam ser gerenciados adequadamente.

Tratamento básico de erros com try e catch

No TypeScript, você lida com erros de tempo de execução usando os blocos try e catch. Essa abordagem permite que você execute código que pode lançar um erro e lidar com esse erro se ele ocorrer.

Exemplo de try e 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

Neste exemplo, a função divide tenta dividir dois números. Se o divisor for zero, um erro é lançado e capturado pelo bloco catch, que registra uma mensagem de erro.

Tipos de erro personalizados

O TypeScript permite que você defina tipos de erro personalizados para representar melhor condições de erro específicas. Tipos de erro personalizados ajudam a categorizar erros e a lidar com eles de forma mais eficaz.

Criando um tipo de erro personalizado

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

Aqui, definimos uma classe de erro personalizada DivisionError que estende a classe interna Error. Usamos esse erro personalizado na função divide para fornecer um tratamento de erro mais específico.

Proteção de tipo com instanceof

Proteções de tipo como instanceof ajudam a restringir o tipo de um objeto de erro no bloco catch, permitindo que você trate diferentes tipos de erro de forma diferente.

Exemplo de proteção de tipo

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

Este exemplo demonstra a proteção de tipo no bloco catch para garantir que o objeto de erro seja uma instância de Error, permitindo um tratamento preciso de erros.

Usando finally para limpeza

O bloco finally pode ser usado para executar código que deve ser executado independentemente de ter ocorrido um erro ou não. Isso é útil para operações de limpeza, como fechar arquivos ou liberar recursos.

Exemplo com 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

Neste exemplo, o bloco finally garante que uma mensagem de limpeza seja registrada independentemente de ocorrer um erro.

Conclusão

O tratamento eficaz de erros é crucial para a construção de aplicativos TypeScript confiáveis. Ao usar try e catch, tipos de erro personalizados, proteção de tipo e finally, você pode gerenciar erros de forma mais eficaz e garantir que seu aplicativo se comporte de forma previsível, mesmo diante de condições inesperadas.

Com essas técnicas, você pode lidar com erros graciosamente e melhorar a robustez do seu código TypeScript. Pratique esses conceitos para se tornar proficiente no tratamento de erros TypeScript e escrever aplicativos mais resilientes.