Erros em JavaScript são objetos com tipo
Quando o JavaScript lança um erro, ele não devolve só uma string — devolve um objeto. Esse objeto tem um tipo (o construtor que o criou) e algumas propriedades padrão: name, message e stack.
err.name é um rótulo curto tipo "TypeError". Já err.message traz a descrição legível pra humanos. E err instanceof TypeError mostra a classe específica. Saber o tipo faz diferença: ele te diz se o problema é um erro de digitação, um valor inválido ou código que nem chegou a ser interpretado.
No total, são sete tipos de erro embutidos no JavaScript. Três você vai ver o tempo todo; os outros quatro aparecem de vez em quando.
SyntaxError: o código nem foi interpretado
Um SyntaxError significa que o JavaScript não conseguiu nem ler o seu código. Na prática, não é um erro de execução — o motor falha durante o parsing, antes de qualquer linha rodar. Você também não consegue capturar um SyntaxError com try/catch no mesmo arquivo, porque o arquivo inteiro é rejeitado.
function greet(name {
return "olá, " + name;
}
// SyntaxError: Unexpected token '{'
Parêntese faltando, uma vírgula perdida, um return fora de uma função — qualquer coisa que quebre a gramática da linguagem dispara esse erro. A solução é sempre corrigir o código-fonte. O único caso em que dá pra capturar um SyntaxError é quando o parsing acontece em tempo de execução, como no JSON.parse:
JSON.parse recebe uma string em tempo de execução, então os erros de sintaxe que ele dispara são capturáveis. Já os erros nos seus próprios arquivos de código-fonte, não.
ReferenceError: esse nome não existe
Um ReferenceError acontece quando você tenta usar uma variável que não foi declarada em nenhum escopo visível para o código atual.
Em 90% dos casos, é um erro de digitação (totl no lugar de total). Os outros 10% são problema de escopo — você está tentando usar algo declarado em outra função ou módulo.
Existe ainda uma causa mais sutil: a temporal dead zone (zona morta temporal). Declarações com let e const passam a existir no topo do bloco, mas você não consegue acessá-las antes da linha onde foram declaradas:
x já é um binding real no momento em que console.log(x) roda, mas ainda não foi inicializado. Por isso o erro de referência. A solução é mover o acesso para depois da declaração.
TypeError: o valor estava no formato errado
Um TypeError significa que o valor até existe, só que ele não é do tipo que a operação espera. Chamar algo que não é uma função, ler uma propriedade de null ou undefined, atribuir valor a uma const — tudo isso gera TypeError.
"Cannot read properties of null (reading 'name')" é, com folga, a mensagem de erro mais comum no JavaScript. Para resolver, você tem duas saídas: garantir que o valor realmente existe, ou proteger o acesso usando optional chaining: user?.name.
Outras variações de TypeError:
Chamar um número como se fosse função, reatribuir uma const, invocar um método que não existe — em todos esses casos o valor não tinha o tipo esperado para a operação que você pediu.
RangeError: quando o número está fora dos limites
O RangeError aparece quando um número é válido em si, mas está fora da faixa permitida para uma operação específica.
Um clássico que dispara esse erro é a recursão infinita, que estoura a pilha de chamadas:
"Maximum call stack size exceeded" quase sempre indica que uma função está chamando a si mesma sem caso-base, ou que duas funções ficam se chamando num loop infinito.
URIError e EvalError: os raros da turma
O URIError aparece quando as funções de manipulação de URI (encodeURI, decodeURIComponent e companhia) recebem uma entrada malformada:
EvalError é uma relíquia. Os motores JavaScript modernos não lançam esse erro para absolutamente nada — ele continua existindo como construtor só por compatibilidade. Dá para criar um na mão, mas você não vai encontrar um no mundo real.
A cadeia de herança
Todos esses tipos herdam de um Error base. Ou seja, err instanceof Error retorna true para qualquer um deles, o que é bem útil em um catch genérico:
Um bloco catch captura tudo — inclusive valores que não são erros, caso alguém faça throw "oops". Esse último caso importa bastante. Sempre valide com instanceof antes de tratar um valor capturado como um objeto Error.
Como lançar erros de propósito em JavaScript
Você mesmo pode lançar qualquer um dos tipos nativos quando seu código detectar um problema. Escolha o tipo que faça sentido com a falha:
Casar o tipo de erro com a falha real não é só frescura — é o que permite que quem chama sua função escreva um catch específico, em vez de ficar dando parse em mensagens de erro.
Classes de erro personalizadas
Quando nenhum dos tipos nativos descreve bem o seu caso, basta estender Error:
Duas coisas importantes aqui: chame super(message) para que o Error base seja inicializado do jeito certo, e defina this.name para que os logs mostrem o rótulo correto. Campos extras como field permitem que quem consome o erro reaja a falhas específicas sem precisar ficar dando parse em string.
A seguir: Console e DevTools
Conhecer os tipos de erro em JavaScript é só metade do caminho — a outra metade é saber ler uma stack trace e inspecionar o estado enquanto o programa roda. O devtools do navegador (e o debugger do Node) transformam aquele "deu erro e não faço ideia do porquê" em poucos segundos de investigação. É o que vem a seguir.
Perguntas frequentes
Quais são os tipos de erro nativos do JavaScript?
O JavaScript traz sete de fábrica: Error (a classe base), SyntaxError, ReferenceError, TypeError, RangeError, URIError e EvalError. Cada um é um construtor que gera um objeto de erro com as propriedades name, message e stack. Na prática, você vai esbarrar com SyntaxError, ReferenceError e TypeError o tempo todo.
Qual a diferença entre SyntaxError e TypeError?
Um SyntaxError significa que o código não é JavaScript válido — o motor nem consegue interpretar. Já o TypeError aparece quando o código foi interpretado normalmente, mas fez algo proibido em tempo de execução, tipo chamar algo que não é função ou acessar uma propriedade de null. Erros de sintaxe travam o script inteiro; erros de tipo só disparam quando aquela linha problemática é executada.
Quando um ReferenceError é disparado em JavaScript?
Quando você usa um nome que não foi declarado ou acessa uma variável let/const dentro da sua temporal dead zone (antes da linha de declaração rodar). Erro de digitação é a causa número um: consoel.log(x) joga um ReferenceError: consoel is not defined. Antes de qualquer coisa, confira a grafia e o escopo.
Dá para criar meus próprios tipos de erro?
Dá sim. Basta estender a classe Error nativa: class ValidationError extends Error { }. Não esqueça de setar o this.name no construtor para que os logs e os blocos catch consigam diferenciar. Vale muito a pena criar classes de erro personalizadas quando falhas diferentes precisam de tratamentos diferentes.