Pular para o conteúdo
Aback Tools Logo

O que é um traceback? Como ler e corrigir o erro

Um traceback mostra o que deu errado, onde e como o programa chegou até ali. Aprenda a anatomia, a ler tracebacks do Python, os seis tipos de exceção mais comuns e o fluxo de depuração.

DH
Tutorials & How-Tos12 min de leitura2,750 palavras

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.

BaseOnde ler primeiroA exceção está sempre no fim
6Tipos mais comunsType, Attribute, Name, Key, Index, Import
1000Limite padrão de framesTeto de recursão do Python

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

Um traceback só é gerado para exceções **não tratadas** - erros que não foram capturados por um bloco `try/except` (Python) ou `try/catch` (JavaScript). Se o seu código captura uma exceção em silêncio, nenhum traceback aparece. Por isso engolir exceções sem registrá-las é um antipadrão de depuração.

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.

- Princípio de depuração em Python

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.

1

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.

2

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.

3

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.

4

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.

Open tool

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çãoO que significaCausa mais comumPrimeiro passo
TypeErrorTipo errado para a operaçãoString onde se esperava intVerifique os tipos das variáveis em torno da linha que falhou
AttributeErrorO objeto não tem esse atributoObjeto None, classe erradaVerifique se a variável pode ser None
NameErrorVariável não definidaErro de digitação, escopo errado, import ausenteVerifique a ortografia e os imports
KeyErrorA chave não existe no dictErro de digitação na chave, dados ausentesUse .get() ou verifique se a chave existe
IndexErrorÍndice de lista fora do intervaloErro de um a mais, lista vaziaVerifique o tamanho da lista antes de indexar
ImportErrorMódulo não encontradoNão instalado, nome erradoInstale 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

`RecursionError: maximum recursion depth exceeded` é um caso especial. O traceback será muito longo - o mesmo frame repetido centenas de vezes. Não tente ler tudo. Olhe o frame repetido para identificar a função presa em recursão infinita e corrija o caso base na lógica dessa função. Aumentar `sys.setrecursionlimit` não é uma correção - apenas adia a queda.

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

Para tracebacks longos com muitos frames, use o [gerador de checklist de causa raiz a partir de stack traces](/tools/data/validators/stack-trace-to-root-cause-checklist-generator) para obter um checklist de depuração estruturado com domínios de falha priorizados - funciona com traces de Python, JavaScript, Java e Go e lida com formatos legíveis e parcialmente minificados.

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

Adicione `RUST_BACKTRACE=1` (Rust) ou `NODE_OPTIONS="--stack-trace-limit=50"` (Node.js) ao seu ambiente de desenvolvimento para obter traces mais completas durante o desenvolvimento. O Python mostra tracebacks completos por padrão - mas em frameworks web como Django e Flask, defina `DEBUG=True` localmente para ver traces completas na resposta do navegador em vez de uma página de erro genérica.

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.

Open tool

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.

Perguntas frequentes

Um traceback é um relatório gerado pelo ambiente de execução de uma linguagem quando ocorre um erro não tratado durante a execução. Ele lista a sequência de chamadas de função ativas no momento em que o erro foi lançado, começando pela chamada mais externa e terminando na linha onde o erro aconteceu. Cada entrada da lista é chamada de frame. O último frame é onde o erro foi lançado; os frames acima mostram como o programa chegou até ali. O traceback dá tudo o que você precisa para encontrar o bug sem usar um depurador.

"Traceback (most recent call last)" é o cabeçalho de todo traceback do Python. Ele informa que a lista de frames a seguir está ordenada com a chamada de função mais recente - a mais próxima do erro - na parte de baixo. Esse é o formato padrão do Python. A última linha depois de todos os frames mostra o tipo de exceção e a mensagem reais. Leia sempre de baixo para cima: primeiro o tipo de exceção, depois o frame no seu próprio código, depois a cadeia de chamadas externa para contexto.

Traceback e stack trace se referem ao mesmo conceito - a cadeia de chamadas registrada no momento em que ocorreu um erro. O Python usa o termo "traceback"; Java, JavaScript, Go e a maioria das outras linguagens dizem "stack trace". Ambos mostram a mesma informação: uma lista de frames, cada um com nome de arquivo, número de linha e nome de função, levando até onde o erro foi lançado. A distinção é puramente terminológica e depende da linguagem.

Comece pela parte de baixo do traceback. A última linha contém o tipo de exceção e a mensagem - isso diz o que deu errado. O bloco penúltimo mostra o arquivo e a linha exatos onde a exceção foi lançada. Suba procurando frames que referenciem arquivos do seu projeto (não caminhos da biblioteca padrão do Python nem de bibliotecas de terceiros). O primeiro frame no seu próprio código é onde o bug provavelmente está. Corrija ali, e não na biblioteca que lançou a exceção, porque a biblioteca está se comportando corretamente diante das entradas que recebeu.

As exceções Python mais comuns que produzem tracebacks são: TypeError (uma operação foi aplicada a um tipo incompatível, por exemplo somar uma string a um inteiro), AttributeError (acesso a um atributo que não existe no objeto), NameError (referência a uma variável que não foi definida), IndexError (acesso a um índice de lista inexistente), KeyError (acesso a uma chave de dicionário ausente) e ImportError/ModuleNotFoundError (o Python não encontrou o módulo que você tentou importar).

Um RecursionError ("maximum recursion depth exceeded") ocorre quando uma função chama a si mesma repetidamente sem um caso base funcional, fazendo a pilha de chamadas crescer até atingir o limite de segurança do Python (padrão de 1000 frames). O traceback de um RecursionError é muito longo - mostra a mesma função repetida centenas de vezes. A correção está sempre na lógica da função: adicionar ou corrigir o caso base, ou reestruturar o algoritmo de forma iterativa. Aumentar o limite de recursão com sys.setrecursionlimit é um contorno, não uma correção.

Um traceback encadeado aparece quando uma exceção é lançada durante o tratamento de outra. O Python mostra as duas exceções separadas por "During handling of the above exception, another exception occurred" ou "The above exception was the direct cause of the following exception." A exceção original (a causa) aparece primeiro e a secundária depois. Para depurar um traceback encadeado, comece pela causa - a exceção original no topo - porque corrigi-la costuma eliminar totalmente a exceção secundária.

Stack traces JavaScript minificados referenciam nomes de arquivo ofuscados e números de linha comprimidos, ilegíveis sem source maps. Os source maps são arquivos .map gerados no processo de build que traduzem as posições minificadas de volta para o código-fonte original. Se você tem os source maps, importe-os em um decodificador de stack trace. Se não tem, o auxiliar de desofuscação de stack traces do Aback Tools ainda consegue identificar padrões de frames aproveitáveis e orientar a depuração a partir de uma trace minificada.

ShareXLinkedIn