programandoai

try/except: capturando o erro antes que ele derrube o programa

Um programa que aceita entrada de usuário vai, cedo ou tarde, receber algo inesperado. A pergunta não é se isso vai acontecer, é o que o programa faz quando acontece.

Estudar esta lição interativa →

Um programa que converte texto digitado por um usuário em número, com int(texto), funciona perfeitamente enquanto o texto for mesmo um número. Mas cedo ou tarde alguém vai digitar "abc", ou deixar o campo vazio, e int("abc") derruba o programa inteiro com ValueError: invalid literal for int() with base 10: 'abc'. A pergunta não é se isso vai acontecer num programa real, é o que o programa faz quando acontece.

entradas = ["10", "abc", "25"]

for entrada in entradas:
    try:
        numero = int(entrada)
        print(f"Convertido: {numero}")
    except ValueError:
        print(f"'{entrada}' não é um número válido, pulando.")

print("Programa continuou até o fim.")

O programa continua rodando mesmo com uma entrada inválida no meio.

try marca um bloco "arriscado", que pode falhar; except TipoDeErro: marca o que fazer se, e somente se, aquele tipo específico de erro acontecer dentro do try. Se nenhum erro acontecer, o bloco except nem chega a rodar, e o programa segue normalmente depois do try.

Pense num try/except como a rede de segurança de um circo: o artista tenta o número arriscado (o try) sabendo que, se cair, a rede (o except) o pega antes de chegar no chão. Sem a rede, uma queda encerraria o espetáculo inteiro; com ela, o show continua.

Dois blocos extras completam a estrutura: else roda só se o try terminou sem nenhum erro; finally roda sempre, com erro ou sem erro, útil para uma limpeza que precisa acontecer de qualquer jeito, como encerrar uma conexão. (Para arquivos o Python tem uma forma ainda melhor, o with, que fecha o arquivo sozinho; você o encontra quando for trabalhar com arquivos.)

try:
    resultado = 10 / 2
    print(f"Resultado: {resultado}")
except ZeroDivisionError:
    print("Não é possível dividir por zero.")
else:
    print("Divisão feita sem nenhum erro.")
finally:
    print("Isto roda sempre, com erro ou sem erro.")
Capture o tipo específico de erro, não qualquer erro

É tentador escrever só except:, sem especificar o tipo, para "pegar qualquer coisa que der errado". Evite isso: um except: genérico também esconde erros de programação de verdade (um nome digitado errado, uma lógica quebrada), fazendo o programa continuar rodando de um jeito silenciosamente errado, em vez de avisar sobre um bug que precisava ser corrigido. Há ainda um agravante: o except: sem tipo também captura o KeyboardInterrupt (o Ctrl+C) e o SystemExit, e o programa deixa de poder ser interrompido. Capturar except ValueError: especificamente deixa claro qual falha você está mesmo esperando e tratando.

Um except do tipo errado deixa o erro passar direto

Se o código dentro do try lançar um ZeroDivisionError, mas o seu except só captura ValueError, o programa não é protegido: o ZeroDivisionError simplesmente não é pego por aquele bloco, e derruba o programa do mesmo jeito, como se o try/except nem existisse para esse caso. Sempre confira se o tipo de exceção no except é realmente o tipo que a operação arriscada pode lançar.

dividendo = 10
divisor = 0

resultado = dividendo / divisor
print(resultado)

Adicione try/except ao redor da divisão.

← Voltar ao índice do curso