Módulo 9 - Erros e exceções: nível avançado

Levantando erros com raise

10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Usar raise para sinalizar uma condição inválida no seu código.
  • Escolher a exceção embutida certa, como ValueError.
  • Escrever mensagens de erro claras e úteis para quem lê.
  • Validar a entrada de uma função antes de processá-la.

O que o raise faz

Até agora você esteve do lado de quem reage: o Python levantava a exceção e você a capturava. O raise inverte esse papel. Com ele, o seu próprio código diz "isto está errado, não dá para continuar" e interrompe a execução ali. Isso é essencial para escrever funções confiáveis. Uma função que calcula a raiz quadrada não deveria aceitar um número negativo em silêncio; ela deveria recusar, com clareza. O raise é como você recusa: em vez de devolver um resultado sem sentido ou um None misterioso, você levanta uma exceção que explica o problema.

import math

def raiz(numero):
    if numero < 0:
        raise ValueError(f"Não existe raiz real de negativo: {numero}")
    return math.sqrt(numero)

print(raiz(9))   # 3.0
print(raiz(-4))  # levanta ValueError

# Traceback (most recent call last):
#   ...
# ValueError: Não existe raiz real de negativo: -4

A função recusa um negativo com raise em vez de devolver um resultado sem sentido.

Repare que, ao chamar raiz(-4), o programa para e mostra um traceback terminando em ValueError com a nossa mensagem. Foi o nosso código, e não o Python, que levantou essa exceção. A escolha do tipo importa: ValueError significa que o valor recebido é do tipo certo, mas o conteúdo é inadequado. Um negativo é um número válido, só não serve para raiz real. Essa é a exceção idiomática para esse caso, e usá-la deixa o seu código previsível para quem o chama.

Validar a entrada antes de processar

Um padrão profissional é validar a entrada logo no início da função, antes de qualquer cálculo. Isso se chama, informalmente, falhar cedo: se o dado é ruim, a função para imediatamente, com uma mensagem que aponta o problema, em vez de arrastar um valor inválido por dezenas de linhas até quebrar em um lugar confuso. Quanto mais perto da causa a função reclamar, mais fácil é consertar. Colocar as verificações no topo também deixa o corpo da função limpo, porque o resto do código já pode confiar que os dados são bons.

def calcular_desconto(preco, percentual):
    if preco < 0:
        raise ValueError(f"Preço não pode ser negativo: {preco}")
    if not 0 <= percentual <= 100:
        raise ValueError(f"Percentual deve estar entre 0 e 100: {percentual}")
    return preco - preco * percentual / 100

print(calcular_desconto(200, 10))   # 180.0
print(calcular_desconto(200, 150))  # ValueError: Percentual deve estar entre 0 e 100: 150

As duas verificações no topo garantem que o cálculo só roda com dados válidos.

Observe como as mensagens ajudam. Elas não dizem apenas "erro": dizem qual regra foi violada e mostram o valor que chegou. Quem receber esse ValueError sabe na hora que passou um percentual de 150, o que não é permitido. Compare com um genérico "entrada inválida", que obriga a pessoa a caçar o problema. Escrever a mensagem pensando em quem vai lê-la no futuro, muitas vezes você mesmo, é parte do capricho do intermediário. Uma boa exceção é meia depuração pronta.

Fixando o raise

O raise é a sua ferramenta para sinalizar problemas com honestidade. Em vez de devolver um valor estranho e esperar que quem chamou perceba, você levanta uma exceção que descreve exatamente o que deu errado. Combine isso com a validação no topo da função e você tem código que falha cedo, com mensagem clara, no lugar certo. Até aqui você usou exceções embutidas como ValueError. Na próxima aula você dá o passo seguinte: criar as suas próprias exceções, com nomes que contam a história do seu programa.

Teste rápido

Quando faz sentido usar raise ValueError dentro de uma função?

Perguntas frequentes

Qual a diferença entre raise e return?
O return devolve um valor e encerra a função de forma normal. O raise interrompe a função levantando uma exceção, que sobe pela pilha até alguém tratá-la com try e except. Use return para o resultado e raise para sinalizar que algo deu errado.
Que tipo de exceção devo levantar?
Escolha a embutida que melhor descreve o problema. ValueError para um valor do tipo certo mas inadequado, TypeError para um tipo errado, KeyError para uma chave ausente. A documentação lista todas. Quando nenhuma encaixa bem, você cria a sua, tema da próxima aula.
Posso levantar uma exceção sem mensagem?
Pode escrever apenas raise ValueError, mas evite. A mensagem é o que ajuda quem vê o erro a entender o que aconteceu. Sempre que possível, explique a regra violada e inclua o valor recebido, como em raise ValueError(f"Percentual inválido: {p}").
O que significa falhar cedo?
É validar os dados logo no início da função e levantar a exceção assim que um valor inválido aparece, em vez de arrastá-lo por muitas linhas. Falhar perto da causa deixa o erro fácil de encontrar e mantém o resto do código confiando em dados bons.
Levantar exceção é melhor que devolver None em caso de erro?
Em geral, sim, para condições realmente inválidas. Devolver None obriga quem chama a lembrar de checar, e um esquecimento vira um bug silencioso mais adiante. Uma exceção não passa despercebida: ou é tratada, ou aparece no traceback, deixando o problema visível.
Posso usar raise dentro de um except?
Sim, é comum. Você pode capturar uma exceção, fazer alguma limpeza ou registro e então levantar de novo com raise sozinho, para repassá-la. Também pode levantar uma exceção diferente. A próxima aula e a seguinte tocam nesse encadeamento com raise from.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.