🚩 Exceções
Uma exceção é um evento que altera o fluxo normal de execução do programa. Em C, por exemplo, uma exceção pode envolver o acesso a uma região inválida de memória com um ponteiro.
Nos sistemas computacionais que usamos diariamente, exceções podem envolver também tentativas de acesso a um recurso que não está disponível no momento, como um servidor de banco de dados que está fora do ar.
Quando não tratadas devidamente, as exceções podem interromper a execução do programa, gerando um comportamento indesejado. É esperado que o sistema consiga reagir às exceções encontradas, inclusive apresentando mensagens de erro aos usuários. Além de auxiliar na resolução do problema, a exibição de mensagens de erro é um fator que contribui bastante para a usabilidade do sistema.
Em JavaScript/TypeScript, há uma classe chamada Error
, que nos auxilia com esse processo. Há uma documentação sobre essa classe, que pode consultada aqui.
Etapas envolvidas
Para lidar com essas situações, utilizamos o conceito de exceções, que permite capturar e tratar erros de forma controlada.
- Lançar uma Exceção: Se um erro é detectado, o programa pode lançar uma exceção usando uma palavra-chave específica (como
throw
em JavaScript). Isso interrompe o fluxo normal do programa e transfere o controle para um bloco de código que pode tratar a exceção.throw new Error("Descreva o erro aqui.");
- Captura e Manipulação: Exceções lançadas são capturadas e tratadas em blocos de código especializados chamados
try...catch
. Enquanto o primeiro engloba a tentativa de operação que pode envolver erro, o bloco catch contém o código que processa a exceção, podendo registrar informações sobre o erro, tentar uma recuperação ou tomar outras ações apropriadas.try { // Trecho que pode gerar uma exceção } catch (erro: any) { // Tratamento da exceção console.log(erro); }
👨🏾💻 Exemplo
Vamos considerar a seguinte situação: temos uma classe Pessoa
com um atributo chamado nome
. De acordo com uma regra da organização, o nome deve ter pelo menos três caracteres.
Para garantir que todas as instâncias da classe Pessoa
atendam a essa regra, precisamos validar o nome tanto no construtor quanto no método set
. Se o nome fornecido for inválido, lançaremos uma exceção usando a classe Error
:
export class Pessoa {
private _nome: string;
constructor(nome: string) {
this.validarNome(nome);
this._nome = nome;
}
set nome(nome: string) {
this.validarNome(nome);
this._nome = nome;
}
get nome(): string {
return this._nome;
}
private validarNome(nome: string): void {
if (nome.length < 3) {
throw new Error("O nome precisa ter pelo menos 3 caracteres.");
}
}
}
No exemplo acima, se tentarmos criar uma instância da classe Pessoa
com um nome inválido (contendo apenas dois caracteres), como em:
let joao: Pessoa = new Pessoa("Jo"); // A exceção será lançada e o programa será interrompido aqui
console.log(joao); // Este código não será executado
A exceção lançada interromperá o fluxo do programa. Para evitar essa interrupção e tratar o erro de forma mais controlada, podemos usar o bloco try...catch
:
try {
let joao: Pessoa = new Pessoa("Jo");
console.log(joao.nome);
}
catch (erro: any) {
console.log(erro.message); // Exibe a mensagem da exceção
}
console.log("O programa continuou...");
Neste código, se o nome for inválido, a exceção será capturada pelo bloco catch
, e a mensagem de erro será exibida. O programa continuará a execução após o bloco catch
, permitindo que o fluxo continue normalmente.
Agora, se o nome for válido, como em:
try {
let joao: Pessoa = new Pessoa("Joao");
console.log(joao.nome);
}
catch (erro: any) {
console.log(erro.message); // Não será executado
}
console.log("O programa continuou...");
Neste caso, a exceção não é lançada, e o programa imprime o nome "Joao"
seguido de "O programa continuou..."
, pois o nome atende ao requisito.
Continuando a execução
No exemplo acima, o objeto joao
só existe dentro do escopo do try
. Para que esse objeto seja usado posteriormente, precisamos antecipar a sua declaração e, após o try...catch
, verificar se ele foi instanciado:
import { Pessoa } from "./Pessoa";
let joao: Pessoa | undefined;
try {
joao = new Pessoa("Jo");
console.log(joao.nome);
} catch (erro: any) {
console.log(erro.message); // Não será executado se não houver erro na criação
}
if (joao instanceof Pessoa) {
console.log("João existe...");
}
🚀 Para testar na prática
📚 Leituras recomendadas
Há outras informações importantes sobre a classe Error
da linguagem JavaScript na documentação elaborada pela Mozilla.