Os erros de JavaScript caem em três categorias distintas - sintaxe, runtime e lógica - e a ferramenta certa para encontrar cada uma é diferente. Um verificador de sintaxe detecta problemas estruturais antes de o motor sequer executar o seu código; um decodificador de erros de runtime explica mensagens enigmáticas depois que surgem; um analisador estático encontra bugs potenciais que nenhuma das abordagens alcança. Este guia associa cada categoria de erro de JavaScript à melhor ferramenta para detectá-la, com fluxos de trabalho para navegador, Node.js e pipelines de CI/CD.
Tipos de erros de JavaScript
Cada erro de JavaScript que encontrar pertence a uma de três categorias, e confundi-las leva a usar a ferramenta errada. Entender primeiro as categorias poupa um tempo considerável de depuração, porque diz exatamente onde procurar e que tipo de verificador ajudará.
Erros de sintaxe
Os erros de sintaxe são detectados pelo parser de JavaScript antes de qualquer linha de código correr. Significam que o motor não consegue interpretar a estrutura do ficheiro - uma chave de fecho em falta, um token inesperado, uma palavra reservada usada como nome de variável ou uma string literal não fechada. O erro é lançado em tempo de análise com um número de linha e uma breve descrição. Um verificador ou validador de sintaxe deteta-os sem executar o código.
Erros de runtime
Os erros de runtime são lançados durante a execução, quando código sintaticamente válido tenta realizar uma operação ilegal. Os mais comuns: aceder a uma propriedade em `null` ou `undefined` (`TypeError`), chamar algo que não é uma função (`TypeError`), referenciar uma variável que não existe (`ReferenceError`) ou dividir por um valor não numérico (`NaN` - que falha em silêncio). Estes erros precisam de um ambiente em execução, um decodificador de stack traces ou análise estática cuidadosa para serem detetados.
Erros de lógica
Os erros de lógica produzem a saída errada sem lançar qualquer erro - um ciclo com desvio de um, uma condição incorreta, uma mutação onde se pretendia uma cópia. Nenhum validador ou verificador de sintaxe os deteta; exigem testes unitários, revisão de código ou uma sessão de debugger. O conjunto de regras do ESLint sobrepõe-se a alguns padrões de erro de lógica (p. ex. sinalizar `==` em vez de `===`), mas a maioria dos bugs de lógica só se encontra executando o código com dados reais.
- SyntaxError: Detectado em tempo de análise - parêntezte em falta, token inválido, string não fechada.
- TypeError: Aceder a `.propriedade` em null/undefined, chamar algo que não é função.
- ReferenceError: Usar uma variável que nunca foi declarada no escopo atual.
- RangeError: Passar um valor fora do intervalo permitido - p. ex. `new Array(-1)`.
- URIError: URI malformada passada a `decodeURIComponent` ou `encodeURIComponent`.
- Bug de lógica: Saída errada, sem erro lançado - exige testes ou um debugger.
Note
Verificadores de sintaxe de JavaScript
Um verificador de sintaxe de JavaScript (também chamado validador de sintaxe) analisa o seu código sem o executar e reporta cada ponto onde a estrutura viola a gramática de JavaScript. É a primeira verificação mais rápida e mais segura - deteta os erros que impediriam o seu código de sequer correr, e fá-lo em milissegundos sem efeitos secundários.
Quando usar um verificador de sintaxe
Os verificadores de sintaxe são úteis em quatro situações: quando recebe JavaScript de um terceiro (um ficheiro gerado, um excerto de documentação ou código colado por um colega), quando depura um script que falha em silêncio num build minificado, quando escreve JavaScript num editor sem suporte de language server, e quando quer uma verificação rápida antes de fazer commit de um ficheiro que editou intensivamente.
O que um verificador de sintaxe deteta e não deteta
| Verificação | Validador de sintaxe | ESLint | Compilador TypeScript |
|---|---|---|---|
| Parêntezte/chave de fecho em falta | ✓ Sim | ✓ Sim | ✓ Sim |
| Token inesperado / sintaxe inválida | ✓ Sim | ✓ Sim | ✓ Sim |
| Referência a variável não definida | ✗ Não | ✓ Com a regra no-undef | ✓ Sim (estrito) |
| Incompatibilidade de tipos | ✗ Não | ✗ Não | ✓ Sim |
| Aviso de variável não usada | ✗ Não | ✓ no-unused-vars | ✓ noUnusedLocals |
| Await em falta em chamada async | ✗ Não | ✓ no-floating-promises | ✓ Sim |
| Lógica / saída errada | ✗ Não | ✗ Não | ✗ Não |
O Validador de sintaxe de JavaScript da Aback Tools corre inteiramente no seu navegador - cole o código, clique em validar e cada erro de sintaxe é destacado com número de linha e mensagem do parser em menos de um segundo. O seu código nunca é enviado a um servidor, o que o torna seguro para scripts proprietários, ferramentas internas e código de aplicação confidencial.
Validador de sintaxe de JavaScript
Verifique código JavaScript em busca de erros de sintaxe instantaneamente - parser local no navegador, diagnósticos por linha, sem upload.
Erros de runtime e stack traces
Os erros de runtime chegam como uma exceção lançada com um tipo, uma mensagem e um stack trace. Lê-los com eficiência é uma habilidade que separa os depuradores rápidos dos lentos. O tipo de erro restringe imediatamente a causa; o stack trace aponta o caminho de execução exato que levou até lá.
Como ler um stack trace de JavaScript
Um stack trace é uma lista de chamadas de funções por ordem inversa - a chamada mais recente no topo, o ponto de entrada no fundo. Cada linha mostra um nome de função, um caminho de ficheiro e um número `line:column`. Comece no topo do trace e desça até encontrar a primeira linha que referencia o seu próprio código (não uma biblioteca como React, Express ou lodash). Essa é a chamada que desencadeou o erro. As linhas acima mostram como chegou lá.
TypeError: Cannot read properties of undefined (reading 'name')
at formatUser (app.js:24:18) // ← o seu código - comece aqui
at renderCard (components.js:51:5) // ← o seu código - cadeia de chamadas
at Array.map (<anonymous>)
at buildList (components.js:44:20)
at App (app.js:12:15)
at React.createElement ...A primeira linha nomeia o tipo de erro (`TypeError`) e a propriedade específica que falhou (`name`). A linha `app.js:24:18` é onde o acesso à propriedade aconteceu. Vá a essa linha - `user.name` onde `user` é undefined - e adicione a proteção adequada: optional chaining (`user?.name`), uma verificação de nulos ou um valor por defeito. O Explicador de stack traces de JavaScript analisa qualquer stack trace e produz automaticamente um desdobramento estruturado da origem, da cadeia de chamadas e da correção mais provável.
Decodificar mensagens de erro de runtime enigmáticas
Algumas mensagens de erro de runtime são diretas; outras são famosas por não ajudar. `"Maximum call stack size exceeded"` significa recursão infinita. `"Cannot set properties of null"` significa que chamou `.setAttribute()` ou similar num elemento do DOM que ainda não existe. `"$ is not defined"` num contexto de navegador significa que o jQuery não foi carregado antes do script que o usa. O Decodificador de erros de runtime de JavaScript aceita qualquer mensagem de erro e devolve uma explicação em linguagem simples com passos de correção específicos para os padrões mais comuns.
Tip
Decodificador de erros de runtime de JavaScript
Cole qualquer mensagem de erro de JavaScript e obtenha uma explicação em linguagem simples com recomendações de correção direcionadas - sem configuração de ambiente.
ESLint e análise estática
O ESLint é a ferramenta de análise estática padrão da indústria para JavaScript e TypeScript. Lê o seu código-fonte sem o executar e aplica um conjunto de regras configurável que deteta problemas desde erros de sintaxe até anti-padrões de segurança. Ao contrário de um verificador de sintaxe, o ESLint compreende escopo, ciclos de vida de variáveis e grafos de imports - o que lhe permite encontrar bugs invisíveis para um parser puro.
O que o ESLint deteta e os verificadores de sintaxe não veem
- Variáveis não definidas: A regra `no-undef` sinaliza qualquer variável usada sem declaração no escopo.
- Variáveis não usadas: `no-unused-vars` previne o acumular de código morto que obscurece a lógica real.
- Igualdade insegura: `eqeqeq` impõe `===` em vez de `==`, eliminando bugs de coerção de tipos.
- Await em falta: `no-floating-promises` (via TypeScript ESLint) deteta chamadas async sem tratamento.
- Código inalcançável: `no-unreachable` sinaliza instruções depois de um `return` ou `throw`.
- Sem console em produção: `no-console` evita que logs de depuração cheguem à produção.
- Regras de segurança: `eslint-plugin-security` sinaliza vulnerabilidades potenciais de injeção e regex inseguros.
Essenciais da configuração do ESLint
O comportamento do ESLint é inteiramente conduzido pelo seu ficheiro de configuração - `.eslintrc.json`, `.eslintrc.js` ou o novo formato flat config `eslint.config.js`. A configuração declara que conjuntos de regras estender (`eslint:recommended`, `plugin:@typescript-eslint/recommended`, `plugin:react/recommended`) e que regras individuais ativar, desativar ou ajustar. Um ficheiro ESLint mal configurado pode desativar silenciosamente regras importantes, e é por isso que validar a própria configuração importa. O Validador de configuração ESLint verifica o seu ficheiro de configuração em busca de erros estruturais e conflitos de regras antes de correr uma passagem de lint.
O valor do ESLint não está nas regras que ativa - está nas regras que a sua equipa concorda em aplicar de forma consistente. Uma configuração partilhada no controlo de versões garante que cada programador vê o mesmo feedback.
Executar o ESLint pela primeira vez
# Instalar ESLint num projeto
npm install --save-dev eslint
# Inicializar um ficheiro de configuração de forma interativa
npx eslint --init
# Analisar um único ficheiro
npx eslint src/app.js
# Analisar um diretório e auto-corrigir problemas seguros
npx eslint src/ --fix
# Saída JSON para ferramentas de CI
npx eslint src/ --format json > eslint-report.jsonNote
Depuração com DevTools do navegador
O Chrome DevTools, o Firefox Developer Tools e o Safari Web Inspector proporcionam a experiência de depuração de JavaScript mais profunda disponível - execução ao vivo, breakpoints, inspeção de variáveis e rastreio de pedidos de rede. Para erros de runtime difíceis de reproduzir localmente, os DevTools são o ambiente principal de investigação.
O painel Consola
O separador Consola mostra cada mensagem registada, aviso e erro lançado em tempo real. Os erros aparecem a vermelho com um stack trace expansível. Clicar na referência ficheiro:linha à direita salta diretamente para o painel Sources nessa localização. O Classificador de erros da consola do navegador complementa os DevTools categorizando os erros da consola por tipo e gravidade - útil quando tem uma saída de consola longa e precisa de triar rapidamente.
Breakpoints e o painel Sources
O painel Sources permite definir breakpoints - pausar a execução numa linha específica e inspecionar cada variável no escopo nesse momento. Clique na numeração de linhas do painel Sources para adicionar um breakpoint e depois recarregue a página ou dispare a ação que causa o erro. Quando a execução pausa, passe o rato sobre qualquer variável para ver o seu valor atual, use o painel Call Stack para ver como chegou lá e avance pelo código linha a linha com F10 (passar por cima) ou F11 (entrar).
Breakpoints condicionais e logpoints
Clique com o botão direito em qualquer número de linha no Sources para adicionar um breakpoint condicional (pausa apenas quando uma condição é verdadeira, p. ex. `user.id === 42`) ou um logpoint (registra um valor sem pausar, como um `console.log` não invasivo). Ambos são extremamente úteis para depurar ciclos e handlers de eventos onde pausar a cada iteração seria impraticável.
| Abordagem de depuração | Melhor para | Deteta erros de runtime | Deteta erros de sintaxe |
|---|---|---|---|
| Validador de sintaxe de JavaScript | Verificação estática pré-execução | ✗ Não | ✓ Sim |
| ESLint | Análise estática, CI/CD | ⚠ Alguns | ✓ Sim |
| Consola dos DevTools do navegador | Erros ao vivo do navegador | ✓ Sim | ✓ Sim |
| Breakpoints dos DevTools | Depuração interativa | ✓ Sim | ✗ Não |
| Decodificador de erros de runtime | Explicar mensagens de erro | ✓ Sim | ✗ Não |
| Explicador de stack traces | Rastrear a origem da chamada | ✓ Sim | ✗ Não |
| Node.js --inspect + Chrome | Depuração do lado do servidor | ✓ Sim | ✓ Sim |
Verificação de erros em CI/CD
A verificação manual de erros durante o desenvolvimento é boa prática mas não é garantia. Automatizar a verificação de erros de JavaScript no seu pipeline de CI/CD garante que nenhum erro de sintaxe, violação do ESLint ou erro de tipo possa fundir-se no ramo principal - independentemente de que programador submeteu o pull request ou de ter corrido verificações localmente.
Um portão de qualidade de CI mínimo
name: JavaScript Quality
on:
pull_request:
paths: ['src/**/*.js', 'src/**/*.ts']
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: ESLint
run: npx eslint src/ --max-warnings 0
- name: TypeScript check
run: npx tsc --noEmitA flag `--max-warnings 0` trata os avisos do ESLint como erros, bloqueando a fusão. Emparelhe com `tsc --noEmit` para projetos TypeScript e detetar erros de tipo que as regras do ESLint não conseguem ver. Ambos os passos saem com código diferente de zero em caso de falha, o que faz falhar o workflow do GitHub Actions e impede que o pull request se funda até os problemas serem resolvidos.
Source maps para o rastreio de erros em produção
Quando um erro de JavaScript chega à produção num bundle minificado, o stack trace mostra nomes de ficheiros comprimidos e números de coluna que são inúteis sem um source map. Os source maps ligam a saída minificada aos ficheiros fonte originais. Antes de fazer deploy, valide que os seus ficheiros de source map estão corretamente estruturados com o Validador de source maps - um source map partido produz stack traces de produção ilegíveis que tornam o diagnóstico de incidentes consideravelmente mais lento.
Warning
Boas práticas de depuração
Bons hábitos de verificação de erros reduzem o tempo gasto a depurar por ordens de grandeza. Estas práticas aplicam-se quer trabalhe num navegador, num serviço Node.js ou numa função serverless.
Corrija o primeiro erro, não todos os erros
Os erros de sintaxe de JavaScript cascateiam - um parêntezte em falta na linha 10 pode produzir cinco erros reportados abaixo dele à medida que o parser perde a noção da estrutura do documento. Corrija sempre primeiro o erro reportado mais acima e depois volte a correr o validador. O que parecia cinco bugs costuma ser um. Isto aplica-se igualmente aos relatórios do ESLint e à saída do compilador TypeScript.
Use modo estrito e funcionalidades modernas da linguagem
Adicionar `"use strict"` a um ficheiro (ou usar módulos ES, que são sempre estritos) converte falhas silenciosas em erros lançados. Atribuir a uma variável não declarada cria silenciosamente uma global em modo permissivo; em modo estrito lança imediatamente um `ReferenceError`. O optional chaining (`?.`), a coalescência nula (`??`) e os valores por defeito na desestruturação de arrays (`const [a = 0] = arr`) reduzem significativamente a superfície dos erros `TypeError: Cannot read properties of undefined`.
Valide os dados externos na fronteira
A maioria das exceções `TypeError` de runtime em produção vem de dados externos - respostas de API, input de utilizador ou valores de localStorage - que não correspondem à forma esperada. Valide os dados recebidos na fronteira: use um validador de schema como Zod ou Joi nas respostas de API, verifique os valores de `localStorage` antes de os analisar como JSON e nunca assuma que um campo existe só porque estava presente nos seus dados de teste. A Calculadora de tamanho de heap de JavaScript é útil quando aparecem erros de memória - ajuda a estimar se uma estrutura de dados grande ou um processo de longa duração excede a alocação de heap do V8.
- Corrija primeiro o primeiro erro: Os erros de sintaxe cascateiam - um problema real produz vários reportados.
- Ative o ESLint no seu editor: O feedback inline em tempo real deteta erros enquanto escreve, não depois do commit.
- Use TypeScript: Erros de tipo detetados em compilação não podem tornar-se erros de runtime em produção.
- Valide dados externos: Respostas de API e input de utilizador devem ser verificados antes de serem usados, não assumidos corretos.
- Escreva testes focados: Testes unitários dos caminhos críticos trazem à superfície erros de lógica que nenhuma ferramenta estática consegue detetar.
- Use source maps: Stack traces de produção legíveis cortam drasticamente o tempo de resposta a incidentes.
Tip
Key takeaways
- Os erros de sintaxe são detetados antes da execução - use o Validador de sintaxe de JavaScript para uma verificação instantânea, local no navegador e sem envio de código.
- Os erros de runtime produzem um tipo e um stack trace - o Decodificador de erros de runtime de JavaScript explica qualquer mensagem de erro em linguagem simples com passos de correção.
- O ESLint deteta problemas que os verificadores de sintaxe não veem: variáveis não definidas, igualdade insegura, imports não usados e `await` em falta - valide a sua configuração ESLint com o Validador de configuração ESLint.
- Corrija sempre primeiro o erro reportado mais acima - os erros de sintaxe cascateiam e um problema real produz vários reportados.
- Adicione o ESLint e o `tsc --noEmit` ao seu pipeline de CI/CD para que nenhum erro se funda sem ser detetado, independentemente da configuração local.
- Os source maps são essenciais para stack traces de produção legíveis - valide-os com o Validador de source maps antes do deploy.
- Valide os dados externos (respostas de API, input de utilizador) na fronteira para eliminar a principal causa de `TypeError: Cannot read properties of undefined` em produção.