Erros são informação, não veredito
Mensagens de erro e stack traces são telemetria do runtime. Desenvolvedores maduros leem, reproduzem, isolam e corrigem — em ciclo curto. Esta aula constrói autonomia diagnóstica; ferramentas auxiliares (incluindo assistentes de IA) só fazem sentido depois que você sabe o que procurar.
Anatomia de um stack trace
TypeError: Cannot read properties of undefined (reading 'total')
at calcularDesconto (app.js:14:28)
at processarPedido (app.js:42:10)
at main (app.js:51:3)
Ordem de leitura: tipo → mensagem → função/linha onde ocorreu → cadeia de chamadas até entrypoint.
Metodologia em quatro passos
- Reproduzir com entrada mínima.
- Isolar — comentar metade, usar console.log estratégico, debugger do VS Code (breakpoint).
- Corrigir causa raiz, não sintoma.
- Registrar teste ou checklist para não regressar.
Debugger prático no VS Code
Configure launch.json para Node: breakpoint na linha suspeita, inspecione variáveis no painel, avance step-by-step. Mais confiável que adicionar dezenas de console.log permanentes.
try / catch com responsabilidade
async function carregarConfig(url) {
try {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (erro) {
console.error('Falha config', { url, message: erro.message });
throw erro;
}
}
Nunca catch vazio. Em produção, logue contexto (request id) sem dados sensíveis.
Erros comuns e tradução
| Mensagem | Significado provável |
|---|---|
| ReferenceError | Variável não declarada ou fora de escopo |
| TypeError | Operação em tipo errado (null, undefined) |
| SyntaxError | Erro de digitação antes da execução |
| RangeError | Valor fora do intervalo permitido |
Construindo resiliência
- Valide entradas na fronteira do sistema (função pública).
- Prefira falhar cedo com mensagem clara.
- Separe lógica pura (fácil de testar) de I/O (rede, arquivo).
Exercício prático: caça ao bug
Cole deliberatemente este código quebrado e pratique diagnóstico:
function resumoPedidos(pedidos) {
let total = 0;
for (let i = 0; i <= pedidos.length; i++) {
total += pedidos[i].valor;
}
return total;
}
console.log(resumoPedidos([{ valor: 100 }, { valor: 50 }]));
Erros esperados: off-by-one no loop (<= em vez de <), possível TypeError no último índice. Corrija, adicione guard para array vazio e teste com três entradas diferentes.
Log estruturado (introdução)
function logErro(contexto, erro) {
console.error(JSON.stringify({
ts: new Date().toISOString(),
contexto,
message: erro.message,
stack: erro.stack
}));
}
JSON em logs facilita busca em ferramentas como Grafana ou CloudWatch — padrão em produção.
Técnica do “rubber duck” e hipóteses
Explique o bug em voz alta (ou por escrito) como se ensinasse um colega. Muitas vezes você encontra a inconsistência no meio da explicação — variável renomeada em um lugar só, condição invertida, objeto mutado inesperadamente. Registre hipóteses antes de testar: “Acho que pedido.cliente chega undefined porque o fetch retorna 204”. Valide ou descarte uma por vez, em vez de alterar dez linhas aleatoriamente.
Debugger no navegador (DevTools)
Na aba Sources, abra seu app.js, clique na margem para breakpoint, recarregue a página e use Step Over / Step Into. Inspecione escopo local e watch expressions. Para bugs de DOM, o painel Elements mostra HTML atual (não o font original) — compare com o que seu JavaScript gerou.
Erros assíncronos
Promises rejeitadas sem catch geram UnhandledPromiseRejection. Em async/await, envolva chamadas externas em try/catch ou use .catch() na cadeia. Erro de rede não é bug de lógica — trate mensagem amigável e retry com limite.
async function carregarPedido(id) {
try {
const res = await fetch(`/api/pedidos/${id}`);
if (res.status === 404) return null;
if (!res.ok) throw new Error(`Falha HTTP ${res.status}`);
return await res.json();
} catch (erro) {
logErro('carregarPedido', erro);
throw erro;
}
}
Checklist de depuração para levar ao trabalho
- Qual é a mensagem exata e a primeira linha da stack?
- Consigo reproduzir com entrada mínima?
- O que mudou desde a última vez que funcionou (git diff)?
- Há diferença entre ambiente local e produção (variáveis, versão)?
- Corrigi a causa ou apenas o sintoma?
Nas próximas semanas, ao integrar web e projetos reais, você aplicará este fluxo diariamente. Só então faz sentido delegar interpretação inicial de traces a assistentes — sempre validando a hipótese no código.
Para aprofundar na web
Para entender melhor este tema, pesquise por:
- "como ler stack trace JavaScript" — ordem das linhas e origem do erro
- "debugger VS Code breakpoint tutorial" — inspecionar variáveis passo a passo
- "try catch async await JavaScript" — erros em código assíncrono
- "ReferenceError TypeError diferença" — tipos comuns e causas
- "logging estruturado JSON aplicações" — padrão usado em produção
Quebre de propósito um script seu e documente no README: mensagem, causa, correção.
Atividades
Onde está a origem imediata do TypeError no exemplo?
Ver resposta
Resposta correta: B) calcularDesconto:14
Primeira linha da stack após a mensagem aponta função e linha do acesso inválido.
Catch vazio é problemático porque:
Ver resposta
Resposta correta: B) Oculta falhas e corrompe estado silenciosamente
Erros engolidos geram incidentes difíceis de rastrear em produção.
Descreva como reproduziria um bug intermitente de produção localmente.
Ver resposta
Coletar logs/stack, identificar entrada e condições (hora, usuário, payload), reduzir ao menor caso que falha, criar fixture de teste, usar debugger ou logs incrementais até achar linha exata.
0 comments