O tratamento de erros em Python é uma habilidade essencial que separa programadores iniciantes de profissionais. Neste guia completo, você aprenderá a usar try except para capturar, tratar e prevenir exceções, criando aplicações robustas e confiáveis.

🎯 O Que é Try Except em Python?

O bloco try/except em Python é a estrutura principal para tratamento de exceções. Ele permite que seu programa detecte erros durante a execução e responda de forma controlada, evitando que a aplicação "crashe" completamente.

A documentação oficial do Python define exceções como erros detectados durante a execução. Ao contrário de erros de sintaxe (que impedem o código de rodar), as exceções ocorrem enquanto o programa está em execução. Você pode aprender mais na documentação oficial do Python.

# Exemplo básico de try/except
try:
    numero = int(input("Digite um número: "))
    print(f"Você digitou: {numero}")
except ValueError:
    print("❌ Erro: Por favor, digite apenas números!")
    numero = 0

📝 Estrutura Completa: Try/Except/Else/Finally

Python oferece quatro blocos principais para tratamento de exceções:

  • try: Contém o código que pode gerar uma exceção
  • except: Executa quando uma exceção ocorre
  • else: Executa quando não há exceção
  • finally: Sempre executa, independentemente de erros
try:
    # Código que pode falhar
    arquivo = open("dados.txt", "r")
    conteudo = arquivo.read()
except FileNotFoundError:
    # O que fazer se o arquivo não existir
    print("❌ Arquivo não encontrado!")
    conteudo = ""
else:
    # Executa apenas se NÃO houver erro
    print("✅ Arquivo lido com sucesso!")
finally:
    # SEMPRE executa (ideal para limpeza)
    print("🔒 Finalizando operação...")
    try:
        arquivo.close()
    except:
        pass

🔍 Tipos de Exceções Mais Comuns

Conhecer os tipos de exceções é fundamental para um tratamento eficaz. Se você já aprendeu sobre variáveis e tipos de dados, sabe que cada tipo de dado pode gerar exceções específicas:

Exceção Descrição Exemplo
ValueError Valor incorreto para operação int("abc")
TypeError Operação com tipo incorreto "2" + 2
IndexError Índice fora do range em listas [1, 2, 3][5]
KeyError Chave não existe em dicionários {"a": 1}["b"]
ZeroDivisionError Divisão por zero 10 / 0
FileNotFoundError Arquivo não encontrado open("x.txt")

💡 Capturando Múltiplos Tipos de Erros

Você pode tratar diferentes exceções de forma específica em um mesmo bloco try:

try:
    numero = int(input("Digite um número: "))
    resultado = 100 / numero
    lista = [1, 2, 3]
    print(lista[numero])
except ValueError:
    print("❌ Erro: Digite apenas números!")
except ZeroDivisionError:
    print("❌ Erro: Não é possível dividir por zero!")
except IndexError:
    print("❌ Erro: Índice fora do range!")
except Exception as e:
    # Captura qualquer outra exceção
    print(f"❌ Erro inesperado: {e}")

🎯 Capturando Informações do Erro

Para entender melhor o que aconteceu, você pode capturar o objeto da exceção:

try:
    numero = int("texto")
except ValueError as erro:
    print(f"Tipo do erro: {type(erro).__name__}")
    print(f"Mensagem: {erro}")
    print(f"String completa: {str(erro)}")

🚨 Levantando Exceções (Raise)

Às vezes, você quer provocar uma exceção intencionalmente, especialmente em funções para validar parâmetros:

def calcular_imc(peso, altura):
    """Calcula IMC com validação"""
    if peso <= 0:
        raise ValueError("O peso deve ser maior que zero")
    if altura <= 0:
        raise ValueError("A altura deve ser maior que zero")
    if altura > 3:
        raise ValueError("Altura em metros deve ser menor que 3")

    return peso / (altura ** 2)

# Usando a função
try:
    imc = calcular_imc(70, 0)
except ValueError as e:
    print(f"❌ Erro de validação: {e}")

🏗️ Criando Exceções Personalizadas

Para sistemas mais complexos, usando Programação Orientada a Objetos, você pode criar suas próprias exceções:

class SaldoInsuficienteError(Exception):
    """Exceção personalizada para saldo insuficiente"""
    def __init__(self, saldo, valor):
        self.saldo = saldo
        self.valor = valor
        mensagem = f"Saldo R${saldo:.2f} insuficiente para R${valor:.2f}"
        super().__init__(mensagem)

class ContaBancaria:
    def __init__(self, saldo_inicial):
        self.saldo = saldo_inicial

    def sacar(self, valor):
        if valor > self.saldo:
            raise SaldoInsuficienteError(self.saldo, valor)
        self.saldo -= valor
        print(f"✅ Saque de R${valor:.2f} realizado!")

# Usando exceção personalizada
conta = ContaBancaria(100)

try:
    conta.sacar(150)
except SaldoInsuficienteError as e:
    print(f"❌ {e}")

💡 Boas Práticas no Tratamento de Erros

  1. Seja específico: Capture exceções específicas em vez de usar except: genérico
  2. Não silencie erros: Sempre registre ou trate o erro adequadamente
  3. Use finally para recursos: Feche arquivos, conexões de banco, etc.
  4. Valide antes de processar: Use try/except como último recurso
  5. Documente exceções: Informe quais exceções suas funções podem lançar
# ✅ BOM - específico e informativo
try:
    arquivo = open("dados.txt")
    dados = json.load(arquivo)
except FileNotFoundError:
    logging.error("Arquivo dados.txt não encontrado")
    dados = {}
except json.JSONDecodeError as e:
    logging.error(f"JSON inválido: {e}")
    dados = {}
finally:
    try:
        arquivo.close()
    except:
        pass

# ❌ RUIM - genérico e silencia tudo
try:
    # código
    pass
except:
    pass  # Silencia todos os erros!

🎯 Exemplo Prático: Sistema Robusto

Combinando estruturas de controle e tratamento de erros:

import logging

# Configurar logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def processar_lista(numeros):
    """Processa lista com tratamento de erros"""
    resultados = []

    for i, num in enumerate(numeros):
        try:
            # Validar se é número
            if not isinstance(num, (int, float)):
                raise TypeError(f"Elemento {i} não é número")

            # Validar não divisão por zero
            if num == 0:
                raise ZeroDivisionError("Divisão por zero não permitida")

            resultado = 100 / num
            resultados.append(resultado)
            logger.info(f"✅ Processou {num}: {resultado:.2f}")

        except TypeError as e:
            logger.error(f"❌ Erro de tipo: {e}")
            resultados.append(None)
        except ZeroDivisionError as e:
            logger.error(f"❌ Erro matemático: {e}")
            resultados.append(None)
        except Exception as e:
            logger.error(f"❌ Erro inesperado: {e}")
            resultados.append(None)

    return resultados

# Usando a função
lista_mista = [2, 5, "texto", 0, 10]
resultados = processar_lista(lista_mista)
print(f"Resultados: {resultados}")

🚀 Próximos Passos

Depois de dominar tratamento de erros, continue sua jornada:

Pronto para dominar Python profissional? Confira nosso curso completo de Python com projetos práticos e boas práticas de indústria!

📝 Resumo

  • ✅ Try/Except captura e trata exceções durante execução
  • ✅ Use except/else/finally para controle completo
  • ✅ Capture tipos específicos de exceções
  • ✅ Use raise para validar entradas
  • ✅ Crie exceções personalizadas com POO
  • ✅ Boas práticas: seja específico, não silencie erros

O tratamento de erros em Python é fundamental para criar aplicações robustas e profissionais. Domine try/except e seus programas estarão prontos para produção!