Um traceback é a forma que o ambiente de execução de uma linguagem tem de dizer exatamente o que deu errado, exatamente onde e exatamente como o programa chegou até ali. Quando ocorre uma exceção não tratada no Python, o traceback é o registro completo de cada chamada de função ativa naquele instante - um mapa preciso do sintoma visível até a causa raiz. Aprender a lê-lo com fluência é uma das habilidades de depuração com maior retorno que você pode desenvolver.
O que é um traceback?
Um traceback (também chamado de stack trace na maioria das outras linguagens) é um relatório de erro estruturado gerado automaticamente pelo ambiente de execução de uma linguagem quando ocorre uma exceção não tratada. Ele registra o estado da pilha de chamadas no exato momento em que o erro foi lançado: a lista de chamadas de função ativas, seus caminhos de arquivo e seus números de linha.
O que um traceback informa
- O que deu errado: o tipo de exceção e a mensagem de erro - a linha mais importante
- Onde aconteceu: o caminho do arquivo e o número de linha de cada frame de função ativo
- Como chegou ali: a cadeia de chamadas completa do ponto de entrada até a linha que falhou
- Qual código é seu: os arquivos do seu projeto aparecem ao lado de frames de bibliotecas e do sistema
Traceback vs. stack trace - mesma coisa, nomes diferentes
O Python usa a palavra "traceback". Java, JavaScript, Go, Ruby e a maioria das outras linguagens dizem "stack trace". Os dois termos descrevem o mesmo conceito - a sequência registrada de frames de função no momento da falha. A distinção é puramente terminológica. Quando um desenvolvedor Python diz "leia o traceback" e um desenvolvedor JavaScript diz "leia o stack trace", eles se referem à mesma ação de depuração.
Note
Anatomia de um traceback
Todo traceback do Python segue a mesma estrutura. Entendê-la permite ir direto à informação útil em vez de ler cada linha de algo que às vezes pode ter centenas de frames.
A linha de cabeçalho
Todo traceback do Python começa com `Traceback (most recent call last):`. Esse cabeçalho informa a convenção de ordenação: a lista de frames que segue vai do mais antigo (mais externo) no topo até o mais recente (mais próximo do erro) embaixo. A expressão "most recent call last" é essencial - o último frame antes da mensagem de exceção é o primeiro que você deve olhar.
Os frames
Cada frame é composto por duas linhas. A primeira mostra o caminho do arquivo, o número de linha e o nome da função no formato `File "caminho/para/arquivo.py", line N, in nome_funcao`. A segunda mostra o código-fonte real daquela linha - reproduzido diretamente do arquivo. Os frames são listados da primeira função chamada (geralmente o script de entrada) até a função que lançou a exceção. O frame mais profundo é o ponto de partida mais importante.
A linha da exceção
A última linha do traceback é a própria exceção: `TipoDeExcecao: texto da mensagem de erro`. O tipo de exceção identifica a categoria do erro (`TypeError`, `ValueError`, `AttributeError`). A mensagem fornece o contexto específico - o valor exato que estava errado, o nome do atributo ausente ou a chave não encontrada. Leia sempre essa linha primeiro.
Leia a última linha primeiro. O tipo de exceção e a mensagem dizem o que deu errado. Tudo acima diz onde.
Como ler um traceback do Python
Ler um traceback com eficiência é uma habilidade que se aprende. O segredo é saber onde olhar primeiro e o que ignorar na primeira passada. A maioria dos desenvolvedores lê de cima para baixo, o que é a direção errada - isso faz perder tempo com o contexto da cadeia externa antes de ter visto o erro.
Leia o tipo de exceção e a mensagem na parte de baixo
Vá imediatamente até a última linha do traceback. `TypeError: unsupported operand type(s) for +: 'int' and 'str'` diz tudo - o operador `+` foi usado entre um inteiro e uma string. `KeyError: 'user_id'` indica que um dicionário foi acessado com uma chave inexistente. Leia essa linha e formule uma hipótese antes de olhar os frames.
Encontre o frame no seu próprio código
Percorra os frames procurando caminhos que pertençam ao seu projeto. Frames de biblioteca (`site-packages`, `lib/python3.x`, `dist-packages`) quase sempre indicam comportamento correto da biblioteca, acionado por uma entrada ruim do seu código. O frame mais profundo que mostra um caminho dentro do seu projeto é onde está o bug. O frame de biblioteca logo abaixo mostra qual função da biblioteca foi chamada com entrada inválida.
Leia a linha de código e o contexto ao redor
Anote o número de linha exato e abra esse arquivo no editor. Leia as 5 a 10 linhas anteriores para entender quais variáveis existem e que valores podem conter. Um `TypeError` em `result = price + tax` se explica ao ver `price = get_price()` duas linhas acima e saber que `get_price()` retorna uma string de uma consulta ao banco, e não um número.
Use um decodificador de traceback para exceções desconhecidas
Para tipos de exceção que você não reconhece, ou cadeias de chamadas profundamente aninhadas entre várias bibliotecas, cole o traceback no explicador de tracebacks do Python. Ele classifica a categoria da exceção, identifica o frame mais aproveitável e fornece passos de depuração concretos - muito mais rápido do que procurar na documentação um tipo de erro desconhecido.
Explicador de tracebacks do Python
Cole qualquer traceback do Python para obter uma explicação em linguagem simples do erro, o frame mais aproveitável e os próximos passos de depuração - no navegador, sem necessidade de conta.
Tipos de traceback comuns em Python
Os seis tipos de exceção mais comuns do Python respondem pela grande maioria dos tracebacks do dia a dia. Reconhecer o tipo pela última linha do traceback permite formular uma hipótese precisa sobre a causa antes mesmo de ler um único frame.
| Tipo de exceção | O que significa | Causa mais comum | Primeiro passo |
|---|---|---|---|
| TypeError | Tipo errado para a operação | String onde se esperava int | Verifique os tipos das variáveis em torno da linha que falhou |
| AttributeError | O objeto não tem esse atributo | Objeto None, classe errada | Verifique se a variável pode ser None |
| NameError | Variável não definida | Erro de digitação, escopo errado, import ausente | Verifique a ortografia e os imports |
| KeyError | A chave não existe no dict | Erro de digitação na chave, dados ausentes | Use .get() ou verifique se a chave existe |
| IndexError | Índice de lista fora do intervalo | Erro de um a mais, lista vazia | Verifique o tamanho da lista antes de indexar |
| ImportError | Módulo não encontrado | Não instalado, nome errado | Instale o pacote com pip, verifique a ortografia |
TypeError: o traceback mais frequente
`TypeError` é a exceção mais comum no Python. Ela dispara sempre que uma operação é aplicada ao tipo errado: chamar algo que não é chamável, somar uma string a um inteiro, passar o número errado de argumentos para uma função. A mensagem costuma ser precisa: `TypeError: can only concatenate str (not "int") to str` não deixa ambiguidade sobre os tipos envolvidos. Identifique qual variável carrega o tipo inesperado e rastreie até onde ela foi atribuída.
AttributeError: a armadilha do None
`AttributeError: 'NoneType' object has no attribute 'split'` é um dos padrões de traceback mais comuns. Significa que uma função retornou `None` quando o seu código esperava uma string (ou outro objeto). O erro não é que `.split()` esteja errado - é que a variável sobre a qual ele foi chamado é `None`. Rastreie até onde a variável foi atribuída. Verifique se a função que a produziu pode retornar `None` em certas condições e adicione uma verificação.
Warning
Tracebacks em outras linguagens
Toda linguagem de programação relevante produz stack traces quando ocorrem erros não tratados. O formato e a terminologia mudam, mas a mesma estratégia de leitura se aplica: encontre primeiro a mensagem de exceção, depois encontre o frame no seu código.
Stack traces de JavaScript e Node.js
Stack traces JavaScript começam com o tipo de erro e a mensagem na primeira linha - o oposto do Python, onde a exceção aparece por último. Cada frame abaixo mostra um nome de função, um caminho de arquivo e linha:coluna. Stack traces do Node.js usam o formato `at NomeDaFuncao (arquivo:linha:col)`. Em JavaScript de navegador, os frames referenciam nomes de arquivo minificados e números de linha comprimidos, a menos que existam source maps. O explicador de stack traces JavaScript decodifica tanto traces legíveis quanto minificadas.
Stack traces de Java e da JVM
Stack traces Java começam com o nome da classe de exceção seguido da mensagem e depois listam frames como `at pacote.Classe.metodo(Arquivo.java:linha)`. Traces Java tendem a ser profundas por causa da hierarquia de classes da JVM - uma única operação pode envolver mais de 20 frames pelas camadas do framework. A mesma regra vale: encontre o primeiro frame no pacote da sua aplicação (não `java.lang`, `springframework` ou outros pacotes de framework) e comece a depurar ali.
Go, Rust e outras linguagens compiladas
Pânicos em Go produzem um stack trace de goroutines mostrando a cadeia de chamadas de cada goroutine no momento da queda. Pânicos em Rust incluem um backtrace quando a variável de ambiente `RUST_BACKTRACE=1` está definida. Ambos seguem o mesmo padrão: a mensagem de erro aparece perto do topo, os frames são listados do mais recente no topo para baixo (o oposto do Python) e o código da sua aplicação aparece intercalado com frames da biblioteca padrão e do runtime. O gerador de checklist de causa raiz a partir de stack traces lida com traces de Go, Rust, Java, JavaScript e Python em uma única ferramenta.
Depurar com tracebacks
Um traceback aponta para o problema, mas corrigi-lo exige entender por que a condição de erro ocorreu - não apenas onde. O fluxo a seguir transforma um traceback bruto em uma correção confirmada com o mínimo de passos.
Reproduza o erro primeiro
Antes de mudar qualquer código, confirme que consegue reproduzir o erro com uma entrada conhecida. Uma correção aplicada a um erro não reproduzível é impossível de testar. Se o traceback veio de um log de produção ou de uma falha de CI, extraia os valores de entrada do contexto do log e escreva um caso de teste mínimo que dispare o mesmo traceback. Isso dá a você um critério de sucesso para a correção.
Decodifique tracebacks de produção
Tracebacks de produção costumam referenciar código minificado, compilado ou transformado. Tracebacks JavaScript de produção normalmente mostram `bundle.js` com um número de linha de um dígito. Tracebacks Python de implantações em contêineres podem referenciar caminhos de arquivo diferentes da sua máquina de desenvolvimento. O auxiliar de desofuscação de stack traces ajuda com traces minificadas identificando padrões estruturais e priorizando os frames mais aproveitáveis mesmo sem source maps.
- Reproduza localmente: extraia as entradas do log e escreva um caso de teste mínimo que falhe
- Isole o frame: identifique qual frame no seu código fez a entrada defeituosa ser passada adiante
- Verifique o tipo: adicione temporariamente `print(type(variavel))` ou `console.log(typeof variavel)` na linha do erro para confirmar os tipos
- Rastreie a atribuição: encontre onde a variável problemática foi atribuída por último e volte até onde o valor errado entrou
- Corrija e execute novamente: confirme que o traceback não aparece mais com a mesma entrada depois da correção
Tip
Boas práticas de traceback
A forma como você trata tracebacks na sua base de código determina a rapidez com que depura problemas em produção, quanto contexto tem quando algo dá errado e com que confiabilidade detecta erros durante o desenvolvimento. Estas práticas tornam os tracebacks mais úteis em todo o ciclo de vida de um projeto.
Sempre registre o traceback completo em produção
Uma exceção de produção reduzida apenas à mensagem de erro, sem traceback, é quase inútil para depurar. Configure seu sistema de logs para capturar o traceback completo: em Python, use `logging.exception("mensagem")` dentro de blocos `except` em vez de `logging.error()`, pois `exception()` inclui automaticamente o traceback atual. No Node.js, registre `error.stack` e não apenas `error.message`. Os poucos bytes extras de armazenamento de log se pagam na primeira vez que um bug é rastreado em menos de um minuto porque todo o contexto foi preservado.
Valide as entradas antes que elas causem tracebacks
Muitos tracebacks são evitáveis com validação de entrada nas fronteiras. Um `TypeError` causado por uma função que recebe `None` em vez de uma string é eliminado verificando a entrada antes de passá-la. Use o validador de sintaxe do Python para detectar erros de sintaxe antes que produzam tracebacks em tempo de execução no import, e adicione anotações de tipo com um verificador como o mypy para detectar erros de tipo estaticamente antes de o código rodar.
Tip
Gerador de checklist de causa raiz a partir de stack traces
Cole qualquer stack trace de Python, JavaScript, Java ou Go para obter um checklist de depuração estruturado com domínios de falha priorizados e passos de resolução - sem cadastro, no navegador.
Key takeaways
- Um traceback é a pilha de chamadas registrada no momento em que ocorre uma exceção não tratada - ele mostra o que deu errado, onde e como o programa chegou ali.
- Leia a última linha primeiro - o tipo de exceção e a mensagem dizem o que deu errado. Os frames acima dizem onde.
- O frame mais aproveitável é o mais profundo no seu próprio código, e não um frame de biblioteca, que normalmente se comporta corretamente diante de entradas ruins do seu código.
- As seis exceções Python mais comuns são TypeError, AttributeError, NameError, KeyError, IndexError e ImportError - reconhecê-las de imediato acelera a depuração.
- Use o explicador de tracebacks do Python para tipos de exceção desconhecidos ou cadeias de chamadas muito aninhadas e obter explicação em linguagem simples e passos de depuração.
- Sempre registre os tracebacks completos (não apenas as mensagens de erro) em produção - um traceback sem frames é quase inútil para depurar depois do fato.
- Valide as entradas nas fronteiras e use anotações de tipo com um verificador estático para impedir que as classes de traceback TypeError e AttributeError cheguem ao tempo de execução.