Workflow de debugging com Claude Code: observar, reproduzir, corrigir e testar
Guia prático de debugging com Claude Code usando TypeScript, Node, Vitest, prompts, testes e CTA.
Claude Code consegue sugerir um fix plausível a partir de um erro, mas debugging em produção precisa de mais do que um patch plausível. Uma sessão confiável separa observação, hipótese, reprodução mínima, implementação e teste de regressão. Sem isso, o bug some de uma tela e volta por outro input, idioma ou deploy.
Este artigo usa TypeScript, Node e Vitest. Combine com Claude Code and TDD quando quiser preservar a condição falha, com error handling patterns quando o modelo de exceção estiver incerto e com build error triage loop quando o comando de prova falhar antes do bug real.
Dê ordem de investigação ao Claude Code
Um pedido vago como “corrija este erro” leva ao primeiro patch razoável. Melhor fornecer erro completo, stack trace, reprodução, formato do input, comportamento esperado, comportamento real e arquivos alterados recentemente. Depois peça três hipóteses antes de editar.
Observação captura fatos. Hipótese explica possível causa. Reprodução mínima transforma hipótese em teste ou script falho. O fix fica estreito e o teste de regressão permanece no repositório.
{
"name": "claude-debug-lab",
"private": true,
"type": "module",
"scripts": {
"test": "vitest run",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "^22.0.0",
"typescript": "^5.6.0",
"vitest": "^3.0.0"
}
}
Exemplo 1: transformar map undefined em regra
O primeiro bug é comum: código chama map em dados que ainda não chegaram. A meta não é só evitar crash. A regra é payload ausente vira lista vazia, nomes em branco saem e nomes válidos são aparados.
export type User = {
id: string;
name?: string | null;
};
export function normalizeUsers(users: User[] | null | undefined): string[] {
if (!Array.isArray(users)) return [];
return users
.filter((user): user is User & { name: string } => typeof user.name === "string")
.map((user) => user.name.trim())
.filter((name) => name.length > 0);
}
import { describe, expect, it } from "vitest";
import { normalizeUsers } from "../src/normalize-users.js";
describe("normalizeUsers", () => {
it("returns an empty list when the API payload is missing", () => {
expect(normalizeUsers(undefined)).toEqual([]);
expect(normalizeUsers(null)).toEqual([]);
});
it("keeps only usable display names", () => {
expect(
normalizeUsers([
{ id: "u1", name: " Masa " },
{ id: "u2", name: "" },
{ id: "u3", name: null },
]),
).toEqual(["Masa"]);
});
});
Use este prompt:
Vemos Cannot read properties of undefined (reading 'map').
normalizeUsers deve tolerar payload API ausente e remover display names em branco.
Adicione primeiro um caso Vitest falho e depois faça o menor fix.
Execute npm test e npm run typecheck no final.
A armadilha é parar em users ?? []. Isso evita crash, mas não define null names, strings vazias e payloads que não são arrays. Dê a regra de produto ao Claude Code, não só a exceção.
Exemplo 2: retry async sem esconder o último erro
Bugs de retry async parecem intermitentes. Um bom teste verifica chamadas, espera, sucesso eventual e falha total. Se o último erro é engolido, a resposta ao incidente perde o sinal do serviço que falhou.
type RetryOptions = {
times: number;
delayMs: number;
sleep?: (ms: number) => Promise<void>;
};
const defaultSleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
export async function retry<T>(
task: () => Promise<T>,
{ times, delayMs, sleep = defaultSleep }: RetryOptions,
): Promise<T> {
let lastError: unknown;
for (let attempt = 1; attempt <= times; attempt += 1) {
try {
return await task();
} catch (error) {
lastError = error;
if (attempt < times) await sleep(delayMs);
}
}
throw lastError instanceof Error ? lastError : new Error("Retry failed");
}
Ao pedir testes, mencione isolamento de mocks, nada de refactor amplo e preservar o último erro. Logs temporários ajudam investigação, mas devem sair do patch final salvo logging estruturado intencional.
Exemplo 3: reproduzir limites de data antes de mexer na UI
O terceiro caso é um bug de limite de data. Na tela parece que o export de março perdeu pedidos de 31 de março, mas a causa costuma estar na comparação entre início do mês selecionado e início do mês seguinte.
export type Order = {
id: string;
createdAt: string;
total: number;
};
export function exportMonthlyOrderIds(orders: Order[], month: string): string[] {
const [yearText, monthText] = month.split("-");
const year = Number(yearText);
const monthIndex = Number(monthText) - 1;
const start = new Date(Date.UTC(year, monthIndex, 1));
const end = new Date(Date.UTC(year, monthIndex + 1, 1));
return orders
.filter((order) => {
const createdAt = new Date(order.createdAt);
return createdAt >= start && createdAt < end;
})
.map((order) => order.id);
}
import { describe, expect, it } from "vitest";
import { exportMonthlyOrderIds } from "../src/export-orders.js";
describe("exportMonthlyOrderIds", () => {
it("includes orders from the first day through the last moment of the month in UTC", () => {
const orders = [
{ id: "feb-end", createdAt: "2026-02-28T23:59:59.999Z", total: 1000 },
{ id: "mar-start", createdAt: "2026-03-01T00:00:00.000Z", total: 2000 },
{ id: "mar-end", createdAt: "2026-03-31T23:59:59.999Z", total: 3000 },
{ id: "apr-start", createdAt: "2026-04-01T00:00:00.000Z", total: 4000 },
];
expect(exportMonthlyOrderIds(orders, "2026-03")).toEqual(["mar-start", "mar-end"]);
});
});
Diga ao Claude Code para não depender do fuso horário local. A regra é incluir o início do mês selecionado e excluir o início do mês seguinte.
Prompt de debugging copiável
Objetivo:
Encontrar a causa, adicionar teste de regressão e corrigir com o menor diff útil.
Observações:
- Erro completo:
- Passos para reproduzir:
- Resultado esperado:
- Resultado real:
- Arquivos alterados recentemente:
Restrições:
- Liste três hipóteses antes de editar.
- Evite refactors amplos.
- Não esconda erros de tipo com any.
- Remova logs temporários no final.
- Execute npm test e npm run typecheck no final.
Relatório:
- Causa raiz
- Arquivos alterados
- Teste de regressão adicionado
- Riscos restantes
Isso transforma Claude Code em parceiro de investigação. Reviewers veem causa, evidência e risco antes de ler todo diff. Em equipes, copie os campos para o review gate para que diff de IA e humano usem o mesmo padrão.
Debugging sem quebrar rota de receita
Em sites públicos, debugging também precisa checar CTA. Um fix de conteúdo pode empurrar o formulário PDF grátis, mudar link Gumroad ou dificultar consulta. Quanto mais popular o artigo, mais importante incluir revenue routing no escopo.
Use uma regra pequena:
const debuggingRoutes = {
first_error: "free_pdf",
repeated_bugfixes: "prompt_templates",
setup_or_ci_blocked: "setup_guide",
team_process_blocked: "consultation",
};
export function chooseDebuggingCta(intent) {
return debuggingRoutes[intent] ?? "free_pdf";
}
console.log(chooseDebuggingCta("repeated_bugfixes"));
O free cheatsheet serve para iniciantes e comparações. 50 Prompt Templates serve para debugging e review repetidos. Setup Guide serve para permissões, CI/CD e setup. Consultoria serve para rollout de equipe e decisões operacionais.
O que foi verificado
Esta reescrita mantém texto UTF-8 limpo, blocos executáveis, links internos, links externos e caminho para PDF grátis, Gumroad e consultoria. Próximas métricas: signups PDF, cliques em Prompt Templates, cliques em Setup Guide e visitas Training deste slug.
Nota de verificação após publicar
Ao publicar artigo de debugging, não termine apenas na correção do código. Abra a URL pública e revise h1, canonical, início do corpo, hero image, formulário PDF grátis, links Gumroad e consultoria. Em artigo popular, melhorar o workflow de debugging pode afetar diretamente a próxima ação do leitor. Se a explicação melhora, mas PDF, Gumroad ou consultoria estão errados, a rota de receita continua incompleta.
Em versões localizadas, exemplos de código podem ser comuns, mas explicação e CTA precisam estar no idioma alvo. O leitor deve entender observação, reprodução, fix e teste sem trocar de idioma. Na revisão com screenshot, olhe início do corpo, área do prompt e área do CTA.
As próximas métricas são signups PDF, cliques em Prompt Templates, cliques em Setup Guide e visitas Training deste slug. Leitores de debugging têm dor ativa, então movimento depois do artigo importa mais que PV bruta.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Workflow Obsidian para CLAUDE.md com Claude Code
Transforme notas de trabalho do Obsidian em notas operacionais CLAUDE.md para preservar contexto.
Claude Code Revenue CTA Routing: artigos para PDF, Gumroad e consultoria
Um fluxo com Claude Code para levar leitores ao PDF grátis, Gumroad ou consultoria conforme intenção.
Regras de handoff para equipes com Claude Code: evidências, permissões, rollback e receita
Formato prático para entregar trabalho do Claude Code com prova, permissões, rollback, PDF grátis, Gumroad e consultoria.