Tipos de Erros - JavaScript

Em um bloco catch, podemos obter informações sobre um erro, que é representado por um objeto. Todos os erros lançados pelo interpretador de JavaScript fornecem um objeto do tipo Error, que possui uma série de propriedades:

  • message: a mensagem de erro

  • name: o tipo de erro

Vale destacar que diferentes navegadores suportam mais algumas propriedades, mas o comportamento delas pode variar dependendo do navegador:

  • fileName: o nome do arquivo JavaScript onde o erro ocorreu

  • lineNumber: a linha no arquivo onde o erro ocorreu

  • columnNumber: a coluna na linha onde o erro ocorreu

  • stack: a pilha de erros

Vejamos como capturar os dados de um erro, por exemplo, ao chamar uma função inexistente:

try {
    callSomeFunc();
{ catch (error) {
    console.log("Tipo de erro:", error.name);
    console.log("Erro:", error.message);
{

Saída do console:

Tipo de erro: ReferenceError
Erro: callSomeFunc is not defined

Lista de Erros

Como vimos acima, o erro lançado pelo interpretador é do tipo Error. No entanto, ao chamar uma função inexistente, é lançado um erro do tipo ReferenceError. O tipo Error representa a categoria geral de erros. Por outro lado, existem tipos específicos de erros para determinadas situações:

  • EvalError: representa um erro que é lançado ao executar a função global eval()

  • RangeError: um erro é lançado se um parâmetro ou uma variável representa um número que está fora de um intervalo aceitável

  • ReferenceError: um erro é lançado ao tentar acessar uma referência que não existe

  • SyntaxError: representa um erro de sintaxe

  • TypeError: um erro é lançado se o valor de uma variável ou parâmetro representa um tipo incorreto, ou ao tentar modificar um valor que não pode ser alterado

  • URIError: um erro é lançado ao passar valores incorretos às funções encodeURI() e decodeURI()

  • AggregateError: fornece um erro que combina várias falhas ocorridas

Por exemplo, ao tentar atribuir um valor a uma constante pela segunda vez, um erro do tipo TypeError é lançado:

try {
    const num = 9;
    num = 7; // Tentativa de reatribuição
} catch (error) {
    console.log(error.name);        // TypeError
    console.log(error.message);     // Assignment to constant variable.
}

Aplicando os Tipos de Erro

Ao lançar erros, podemos utilizar tipos de erro integrados. Por exemplo:

class Person {
  constructor(name, age) {
      if (age < 0) throw new Error("A idade deve ser positiva");
      this.name = name;
      this.age = age;
  }
  print() { console.log(`Name: ${this.name}  Age: ${this.age}`); }
}

try {
  const tom = new Person("Tom", -45);
  tom.print();
}
catch (error) {   
  console.log(error.message); // A idade deve ser positiva
}

Aqui, o construtor da classe Person recebe valores para o nome e a idade da pessoa. Se a idade fornecida for negativa, é lançado um erro na forma de um objeto Error. A mensagem de erro é passada como parâmetro para o construtor de Error:

if (age < 0) throw new Error("A idade deve ser positiva");

Assim, ao processar a exceção no bloco catch, podemos obter a mensagem de erro transmitida.

Todos os outros tipos de erro também aceitam uma mensagem de erro como primeiro parâmetro no construtor. Vamos lançar alguns tipos de erros:

class Person {
  constructor(pName, pAge) {
      const age = parseInt(pAge);
      if (isNaN(age)) throw new TypeError("A idade deve ser um número");
      if (age < 0 || age > 120) throw new RangeError("A idade deve ser maior que 0 e menor que 120");
      this.name = pName;
      this.age = age;
  }
  print() { console.log(`Name: ${this.name}  Age: ${this.age}`); }
}

try {
  const tom = new Person("Tom", -45);
}
catch (error) {   
  console.log(error.message); // A idade deve ser maior que 0 e menor que 120
}

try {
  const bob = new Person("Bob", "bla bla");
}
catch (error) {   
  console.log(error.message); // A idade deve ser um número
}

try {
  const sam = new Person("Sam", 23);
  sam.print();    // Name: Sam  Age: 23
}
catch (error) {   
  console.log(error.message);
}

Saída no console:

A idade deve ser maior que 0 e menor que 120
A idade deve ser um número
Name: Sam  Age: 23

Nesse exemplo, como a idade pode ser qualquer valor, inicialmente tentamos convertê-la em um número usando a função parseInt():

const age = parseInt(pAge);
if (isNaN(age)) throw new TypeError("A idade deve ser um número");

Em seguida, com a função isNaN(age), verificamos se o número obtido é de fato um número. Se age não for um número, a função retorna verdadeiro. Portanto, é lançado um erro do tipo TypeError.

Depois verificamos se o número está dentro do intervalo aceitável. Se não estiver, lançamos um erro do tipo RangeError:

if (age < 0 || age > 120) throw new RangeError("A idade deve ser maior que 0 e menor que 120");

Tratando Múltiplos Tipos de Erro

Quando executamos o mesmo código, podem ser lançados erros de diferentes tipos. E às vezes é necessário distinguir entre os tipos de tratamento. Neste caso, podemos verificar o tipo de erro que ocorreu. Por exemplo, o exemplo acima com a classe Person:

class Person {
  constructor(pName, pAge) {
      const age = parseInt(pAge);
      if (isNaN(age)) throw new TypeError("A idade deve ser um número");
      if (age < 0 || age > 120) throw new RangeError("A idade deve ser maior que 0 e menor que 120");
      this.name = pName;
      this.age = age;
  }
  print() { console.log(`Name: ${this.name}  Age: ${this.age}`); }
}

try {
  const tom = new Person("Tom", -45);
  const bob = new Person("Bob", "bla bla");
}
catch (error) {
  if (error instanceof TypeError) {
      console.log("Tipo de dado incorreto.");
  } else if (error instanceof RangeError) {
      console.log("Valor inaceitável");
  }
  console.log(error.message);
}

Criando Seus Próprios Tipos de Erro

Não estamos limitados apenas aos tipos de erro integrados e podemos criar nossos próprios tipos de erro para situações específicas. Por exemplo:

class PersonError extends Error {
  constructor(value, ...params) {
      super(...params);
      this.name = "PersonError";
      this.argument = value;
  }
}

class Person {
  constructor(pName, pAge) {
      const age = parseInt(pAge);
      if (isNaN(age)) throw new PersonError(pAge, "A idade deve ser um número");
      if (age < 0 || age > 120) throw new PersonError(pAge, "A idade deve ser maior que 0 e menor que 120");
      this.name = pName;
      this.age = age;
  }
  print() { console.log(`Name: ${this.name}  Age: ${this.age}`); }
}

try {
  const bob = new Person("Bob", "bla bla");
}
catch (error) {
  if (error instanceof PersonError) {
      console.log("Erro do tipo Person. Valor incorreto:", error.argument);
  }
  console.log(error.message);
}

Saída no console:

Erro do tipo Person. Valor incorreto: bla bla
A idade deve ser um número

O tipo de erro PersonError é definido aqui, herdado da classe Error:

class PersonError extends Error {
  constructor(value, ...params) {
      super(...params);
      this.name = "PersonError";
      this.argument = value;
  }
}

No construtor, definimos uma propriedade adicional chamada argument, que armazenará o valor que causou o erro. Usamos o parâmetro value do construtor para obter esse valor. Além disso, redefinimos o nome do tipo de erro usando a propriedade this.name.

Na classe Person, usamos esse tipo, passando os valores correspondentes para o construtor de PersonError:

if (isNaN(age)) throw new PersonError(pAge, "A idade deve ser um número");
if (age < 0 || age > 120) throw new PersonError(pAge, "A idade deve ser maior que 0 e menor que 120");

Depois, ao tratar a exceção, podemos verificar o tipo e, se for um PersonError, acessar sua propriedade argument:

catch (error) {
  if (error instanceof PersonError) {
      console.log("Erro do tipo Person. Valor incorreto:", error.argument);
  }
  console.log(error.message);
}
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com